silverlight wpf Command提交时输入验证
silverlight 或WPF在MVVM模式中使用INotifyDataErrorInfo接口对输入进行验证时
控件lostFocus时会触发验证,但在提交动作(例如button的Command)时,不触发
验证。下面的方法提供控件输入验证统一触发。
1、添加ValidationScope类
public class ValidationScope
{
public FrameworkElement ScopeElement { get; private set; } private readonly ObservableCollection<ValidationError> _errors = new ObservableCollection<ValidationError>(); public ObservableCollection<ValidationError> Errors
{
get { return _errors; }
} public bool IsValid()
{
return _errors.Count == ;
} public static string GetValidateBoundProperty(DependencyObject obj)
{
return (string)obj.GetValue(ValidateBoundPropertyProperty);
} public static void SetValidateBoundProperty(DependencyObject obj, string value)
{
obj.SetValue(ValidateBoundPropertyProperty, value);
} public static readonly DependencyProperty ValidateBoundPropertyProperty =
DependencyProperty.RegisterAttached("ValidateBoundProperty", typeof(string), typeof(ValidationScope), new PropertyMetadata(null)); public static ValidationScope GetValidationScope(DependencyObject obj)
{
return (ValidationScope)obj.GetValue(ValidationScopeProperty);
} public static void SetValidationScope(DependencyObject obj, ValidationScope value)
{
obj.SetValue(ValidationScopeProperty, value);
} public static readonly DependencyProperty ValidationScopeProperty =
DependencyProperty.RegisterAttached("ValidationScope", typeof(ValidationScope), typeof(ValidationScope), new PropertyMetadata(null, ValidationScopeChanged)); private static void ValidationScopeChanged(DependencyObject source, DependencyPropertyChangedEventArgs args)
{
ValidationScope oldScope = args.OldValue as ValidationScope;
if (oldScope != null)
{
oldScope.ScopeElement.BindingValidationError -= oldScope.ScopeElement_BindingValidationError;
oldScope.ScopeElement = null;
} FrameworkElement scopeElement = source as FrameworkElement;
if (scopeElement == null)
{
throw new ArgumentException(string.Format(
"'{0}' is not a valid type.ValidationScope attached property can only be specified on types inheriting from FrameworkElement.",
source));
} ValidationScope newScope = (ValidationScope)args.NewValue;
newScope.ScopeElement = scopeElement;
newScope.ScopeElement.BindingValidationError += newScope.ScopeElement_BindingValidationError;
} private void ScopeElement_BindingValidationError(object sender, ValidationErrorEventArgs e)
{
if (e.Action == ValidationErrorEventAction.Removed)
{
Errors.Remove(e.Error);
}
else if (e.Action == ValidationErrorEventAction.Added)
{
Errors.Add(e.Error);
}
} public void ValidateScope()
{
ForEachElement(ScopeElement, delegate(DependencyObject obj)
{
// TODO - some of this reflection could be cached to improve performance
string propertyName = GetValidateBoundProperty(obj);
if (!string.IsNullOrEmpty(propertyName))
{
FrameworkElement element = (FrameworkElement)obj;
var field = element.GetType().GetFields(BindingFlags.Static | BindingFlags.FlattenHierarchy | BindingFlags.Public)
.Where(p => p.FieldType == typeof(DependencyProperty) && p.Name == (propertyName + "Property"))
.FirstOrDefault(); if (field == null)
{
throw new ArgumentException(string.Format(
"Dependency property '{0}' could not be found on type '{1}'; ValidationScope.ValidateBoundProperty",
propertyName, element.GetType()));
}
var be = element.GetBindingExpression((DependencyProperty)field.GetValue(null));
be.UpdateSource();
}
});
} private static void ForEachElement(DependencyObject root, Action<DependencyObject> action)
{
int childCount = VisualTreeHelper.GetChildrenCount(root);
for (int i = ; i < childCount; i++)
{
var obj = VisualTreeHelper.GetChild(root, i);
action(obj);
ForEachElement(obj, action);
}
}
}
2、在包含输入控件的容器控件添加依赖属性ValidationScope(ViewModel里的ValidationScope实例)
xaml:
<containers:ContainerPanel Grid.Row="" Margin="" Title="挂起工单列表" TitleHorizontalAlignment="Left" TitleMargin="10,10,0,10" validation:ValidationScope.ValidationScope="{Binding ValidationScope1}">
3、每个需要验证的控件添加依赖属性ValidateBound,指定要验证控件的哪个属性
<TextBox Text="{Binding ApproveContent,Mode=TwoWay}" validation:ValidationScope.ValidateBoundProperty="Text"/>
4、ViewModel中定义ValidationScope实例
private ValidationScope _validationScope1 = new ValidationScope();
public ValidationScope ValidationScope1
{
get { return _validationScope1; }
set
{
_validationScope1 = value;
this.RaisePropertyChanged(() => ValidationScope1);
}
}
5、在要触发验证的Command中调用验证方法
public DelegateCommand ApproveCommand
{
get
{
if (_approveCommand == null)
{
_approveCommand = new DelegateCommand(() =>
{
ValidationScope1.ValidateScope(); if (!ValidationScope1.IsValid())
{
CommonNotification.Raise(new Notification() { Content = new UWay.NOAP.DTO.MsgInfo() { IsSuccess = true, Content = "要审批的工单需要填写审批内容!" }, Title = "提示" });
}
else
{
ApproveBatch();
} }, () => _canApprove);
}
return _approveCommand;
}
}
silverlight wpf Command提交时输入验证的更多相关文章
- 给trac的ticket添加提交时字段验证
我们在项目管理中使用了trac系统,并且对于ticket添加了以下自定义字段并且对它们的格式都有一定要求: svn版本号:格式为 r1234.多个版本号之间使用半角逗号隔开.如:r1234,r5678 ...
- vux中表单验证,在提交时自动聚焦到未验证通过的那栏;及循环表单的验证
首先vux中的表单验证在点击触发,失焦时才显示错误信息,如果不管它,它就没反应,这显然是不合理的:解决办法就是:在提交时做验证,不通过的话就使用.focus()及.blur()方法给它聚焦,失焦. i ...
- easyui form提交时验证必填,打开时不显示必填提示
给textbox添加required:true属性后,打开页面时整个表单都是红的,需要将其设置为提交时再验证. 解决方法:通过textbox的novalidate属性来控制是否开启验证 <inp ...
- [转]jQuery.validate插件在失去焦点时执行验证代码
转:http://my.oschina.net/enyo/blog/311566 关于 jquery.validate.js 表单验证插件如何在失去焦点时做验证.看手册后发现默认是在表单提交时执行验证 ...
- 设置Git提交时不用输入用户名和密码
在用git提交时代码至github上时每次都要输入用户名和密码,当提交操作较为频繁时非常不方便,可以按下文中的介绍,设置成提交时不用输入用户名和密码: 1.在当前库下,已经运行过 git remote ...
- VisualSVN设置提交时必须输入日志信息
VisualSVN设置提交时必须输入日志信息 1.svn提交时强制输入提交信息 为了阻止SVN提交空日志信息和垃圾文件可以在SVN服务器端强制必须填写日志信息,这时需用到pre-commit钩子脚本. ...
- WPF学习笔记(8):DataGrid单元格数字为空时避免验证问题的解决
原文:WPF学习笔记(8):DataGrid单元格数字为空时避免验证问题的解决 如下图,在凭证编辑窗体中,有的单元格不需要数字,但如果录入数字后再删除,会触发数字验证,单元格显示红色框线,导致不能执行 ...
- 当页面提交时,执行相关JS函数检查输入是否合法
当页面提交时,执行相关JS函数检查输入是否合法 关键代码 <form action="tj.php" method="post" onSubmit=&qu ...
- Struts2入门(四)——数据输入验证
一.前言 1.1.什么是输入验证?为什么需要输入验证? 在上一篇文章中,我们学习了数据类型转换,我们提到了表示层数据处理的两个方法,也提到了用户输入数据需要进行类型转换才能得到我们想要的数据,那么,我 ...
随机推荐
- .net mvc Model 验证总结
ASP.NET MVC4中的Model是自验证的,这是通过.NET4的System.ComponentModel.DataAnnotations命名空间完毕的. 我们要做的仅仅是给Model类的各属性 ...
- poj2947Widget Factory
对于同余方程的高斯消元啊. 其实也差不多吧.先同一位通分,然后减一下就好了. 主要是判无解和多解的麻烦,需要注意即使有自由元也可能先无解 #include<cstdio> #include ...
- 0x20 搜索
这里基本就是入门吧. 可达性统计 用bitset搞的判重,发现这东西是真好用哈,空间还小 #include<cstdio> #include<iostream> #includ ...
- Linux平台Oracle多个实例启动
如何在Linux系统中启动多个Oracle实例?相信很多Oracle的初学者都会碰到这一类问题,下面我简单介绍一下. 1.切换Oracle用户: # su oracle 2.切换到Oracle目录下: ...
- python之路——装饰器函数
阅读目录 楔子 装饰器的形成过程 开放封闭原则 谈装饰器主要功能和装饰器固定结构 带参数的装饰器 多个装饰器装饰一个函数 返回顶部 楔子 作为一个会写函数的python开发,我们从今天开始要去公司上班 ...
- String or binary data would be truncated 异常解决办法 .
原因:一般出现这个问题是因为数据库中的某个字段的长度小,而插入数据大解决:修改表结构,使表字段大小相同或大于要插入的数据
- 在C#中运行PowerShell
C#中运行PowerShell需要用到System.Management.Automation.dll.在Visual Studio中可以通过NuGet添加引用,package名字为"Sys ...
- .NET XML POST 请求
//请求体,XML参数 string xmlstring = @"<root></root>“; //请求URL string postUrl ="http ...
- SwipeRefreshLayout的使用,下拉刷新
1. <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android ...
- 读书笔记之《HTML5 与 CSS3 基础教程》
1· 读前预期 考虑到对于 Web 开发零基础,凡涉足一件未知的任务,最好先理清任务的逻辑结构,然后有目的地逐步学习.为实现我们的需求和设计,必须要学习前端.后端.服务器等一系列暂时陌生的知识,在此, ...