你走错了路。
在 MVVM 中处理验证的一个好方法是在绑定上实现和设置IDataErrorInfo
。您几乎肯定也希望启用完整性,以便绑定引擎触发您已将属性绑定到的控件上的附加事件。ValidatesOnDataErrors
true
ValidatesOnExceptions
NotifyOnValidationError
Validation.Error
有关更多详细信息,请参阅MSDN 文档中有关WPF中的数据绑定的验证部分。
一些技巧:
- .NET 4.5 引入
INotifyDataErrorInfo
了相应的绑定属性,与;ValidatesOnNotifyDataErrors
相比提供了增强的验证功能。IDataErrorInfo
你可能想调查一下。
- 您实际上不需要在内部做任何有意义的事情,
IDataErrorInfo.Error
因为它由 Windows 窗体基础结构使用并且在 WPF 中被忽略。您甚至可以使用 getter throw NotImplementedException
。
- 这里和这里有很好的阅读材料来说明这种方法,并附有示例和代码。
更新:澄清和示例代码
这个验证模型根本不涉及实现ValidationRule
你自己;您的模型(即绑定源)只需要实现两个接口之一。如何实现接口完全取决于您;在过去的一个项目中,我实现了基本的异步验证
public interface IDelegatedValidation : IDataErrorInfo
{
/// <summary>
/// Occurs when validation is to be performed.
/// </summary>
event EventHandler<DelegatedValidationEventArgs> ValidationRequested;
}
public class DelegatedValidationEventArgs : EventArgs
{
public DelegatedValidationEventArgs(string propertyName)
{
this.PropertyName = propertyName;
}
public string PropertyName { get; private set; }
public bool Handled { get; set; }
public string ValidationError { get; set; }
}
该模型IDelegatedValidation
通过公开一个事件并使用
string IDataErrorInfo.this[string columnName]
{
get { return this.GetValidationError(columnName); }
}
private string GetValidationError(string propertyName)
{
var args = new DelegatedValidationEventArgs(propertyName);
this.OnValidationRequested(args);
return args.ValidationError;
}
protected virtual void OnValidationRequested(DelegatedValidationEventArgs args)
{
var handler = this.ValidationRequested;
if (handler == null) {
return;
}
foreach (EventHandler<DelegatedValidationEventArgs> target in handler.GetInvocationList()) {
target.Invoke(this, args);
if (args.Handled) {
break;
}
}
}
所以工作流程是这样的:
- 当模型即将被视图模型包装时,一些可以执行验证的适当实体订阅它的
ValidationRequested
事件。
- 视图绑定到模型;在某些时候触发验证。
- 该模型调用
GetValidationError
.
- 事件处理程序被一一调用;第一个产生验证错误的处理程序设置
args.ValidationError
并args.Handled
停止true
链。
- 验证错误返回到视图。
如果视图模型需要知道它的模型是否有效(例如启用/禁用“保存”命令),它还需要进入这个过程。
真的没有什么是你不能用IDataErrorInfo
/做的,INotifyDataErrorInfo
因为你如何实现它们完全取决于你。一定要查看后者文档的Silverlight 版本以获取更多示例;互联网上也有很多类似的有用材料。