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.什么是输入验证?为什么需要输入验证? 在上一篇文章中,我们学习了数据类型转换,我们提到了表示层数据处理的两个方法,也提到了用户输入数据需要进行类型转换才能得到我们想要的数据,那么,我 ...
随机推荐
- UNIX环境高级编程(5):文件I/O(1)
UNIX系统中的大多数文件I/O仅仅须要用到5个函数:open.read.write.lseek以及close.本章说明的函数常常称为"不带缓冲的I/0",术语不带缓冲指的是每一个 ...
- mysqil操作数据库
mysqil操作数据库 每次用到mysql_connect连接数据库的时候都会提示: 1 Deprecated: mysql_connect(): The mysql extension is dep ...
- 5.文件I/O
1 C标准函数与系统函数的区别 文件的结构体: 1.1 I/O缓冲区 每一个FILE文件流都有一个缓冲区buffer,默认大小8192Byte. 1.2 效率 文件缓冲区会降低效率.这里提供缓冲区主要 ...
- 20.QT文本文件读写
#include "mainwindow.h" #include "ui_mainwindow.h" #include <QFile> #inclu ...
- $.ajax 和$.post的区别
https://blog.csdn.net/weixin_39709686/article/details/78680754
- Mac 安装cmake小问题
今天用 brew install cmake. ==> Downloading https://homebrew.bintray.com/bottles/cmake-3.9.6.sierra.b ...
- 使用pgpool管理数据库集群故障的问题
pgpool如何选举master角色 在pgpool启动的过程中通过对 pgpoo.conf配置文件中的数据库节点条目信息,对集群中的数据库节点从0开始一个个的遍历,并发送SQL语句“select p ...
- C#基础篇之语言和框架介绍
1.如何描述C#和.NET的关系? .Net的是平台,C#是为了微软公司为了.NET平台开发的面向对象语言. 2.C#能做什么? (1)C#.NET做窗体应用开发,Web开发中可以通过WCF编写Web ...
- 第四章 Python之文件处理
文件操作 文件操作一般分为三步:打开文件得到文件句柄并赋值给一个变量--->通过句柄对文件进行操作-->关闭文件 f=open(r'C:\Users\hesha\PycharmProjec ...
- Pyhton学习——Day60
Form组件 - form表单(验证:保留上次内容) - - Ajax(验证:无需上次内容) - 返回HttpResponse - 前端:跳转或错误信息 1. Form组件扩展: 1.简单扩展 利用F ...