.net WPF中的交叉属性验证
目前,我正在使用.net WPF中的交叉属性验证,.net,wpf,validation,mvvm,idataerrorinfo,.net,Wpf,Validation,Mvvm,Idataerrorinfo,目前,我正在使用IDataErrorInfo接口在WPF应用程序中实现验证。作为该接口一部分的索引器允许验证单个属性,如下所示: public string this[string columnName] { get { switch (columnName) { case "LastName": if (string.IsNullOrEmpty(this.LastName))
IDataErrorInfo
接口在WPF应用程序中实现验证。作为该接口一部分的索引器允许验证单个属性,如下所示:
public string this[string columnName]
{
get
{
switch (columnName)
{
case "LastName":
if (string.IsNullOrEmpty(this.LastName))
return "LastName must not be empty.";
break;
// case, case, case, etc., etc.
}
return null;
}
}
public string this[string columnName]
{
get
{
switch (columnName)
{
case "ShippingDate":
case "InvoiceDate":
if (this.ShippingDate > this.InvoiceDate)
return "Invoice date must not be before shipping date.";
break;
}
return null;
}
}
如果发生验证错误,我会在文本框旁边显示一个带工具提示的星号
如果我有与单个属性不严格相关的验证规则,我该怎么办?例如,如果表示订单的域实体具有发货日期和发票日期,并且我希望验证发票日期必须晚于或等于发货日期的规则
当然,我也可以通过两次检查关系,一次检查columnName“ShippingDate”,一次检查columnName“InvoiceDate”,然后在UI的两个输入字段中用星号标记错误,将此规则强制输入到索引器中,如下所示:
public string this[string columnName]
{
get
{
switch (columnName)
{
case "LastName":
if (string.IsNullOrEmpty(this.LastName))
return "LastName must not be empty.";
break;
// case, case, case, etc., etc.
}
return null;
}
}
public string this[string columnName]
{
get
{
switch (columnName)
{
case "ShippingDate":
case "InvoiceDate":
if (this.ShippingDate > this.InvoiceDate)
return "Invoice date must not be before shipping date.";
break;
}
return null;
}
}
但我更希望独立于索引器进行“对象级别”或“跨属性”验证(索引器应仅报告无效的“单一属性状态”),并在UI上单独显示这些对象级别或关系错误
我希望IDataErrorInfo
接口的Error
属性可以用于对象级验证。例如,当我在文本框的绑定表达式中指定validateSondaerRors=True
时,WPF调用索引器进行属性验证。但是,每当我更改输入字段中的某些数据时,我找不到一种方法来告诉WPF调用Error
属性。也许我对这房子用途的猜测是错误的
如何在WPF中实现跨属性验证?
提前感谢您的建议 关于我的问题,我是否可以设置绑定,以便WPF自动测试
IDataErrorInfo
接口的Error
属性,我发现以下否定答案:
有人问:
基本上,我想知道一个
将触发
IDataErrorInfo.错误的测试,在
验证数据错误的方法
导致测试
IDataErrorInfo.Item
Microsoft Online Community Support的答复:
设置ValidateSondaErrors
仅绑定类的属性
IDataErrorInfo.项目的测试和
不是IDataErrorInfo.Error的错误
绑定类不提供
属性来检查
IDataErrorInfo。错误为
ValidatesOnDaerRors属性到
到目前为止,请检查IDataErrorInfo.项目
为了得到你想要的,我们必须建立
数据绑定到
IDataError。错误
因此,Error
属性没有比在域实体中定义我自己手工制作的属性(如CrossPropertyErrors
)更多的值。WPF不支持以简单的内置方式测试Error
属性
编辑:以上引用自2008年3月,因此很可能与.NET3.5有关。但我在.NET4.0中找不到任何迹象表明这一点发生了变化
编辑:最后,我必须创建自己的手写绑定到错误
属性,并用适当的跨属性错误消息填充它。现在,类中任何其他属性的每次更改都会引发已更改属性本身和Error
属性的PropertyChanged
事件,以刷新UI上的错误消息
编辑2
大致如下:
模型(或视图模型)类:
公共类SomeModel:NotificationObject,IDataErrorInfo
{
私有字符串\u someProperty;
公共字符串属性
{
获取{return\u someProperty;}
设置
{
if(_someProperty!=值)
{
_someProperty=值;
RaisePropertyChanged(“SomeProperty”、“Error”);
//这是关键:对于每一个更改的属性,都有一个更改
//还会引发错误属性的通知
}
}
}
//对于模型的每个属性,上述操作都会重复
#区域IDataErrorInfo成员
公共字符串错误
{
得到
{
var sb=新的StringBuilder();
//例如。。。
如果(发票日期<发货日期)
sb.附录(“发票日期不得早于发货日期”);
//更多跨属性验证…我们只有一个错误
//字符串,因此我们用
//某人附加一句话(“另一条信息…”)等。
//可以全部移动到单独的验证类中
//保持模型类更干净
使某人返回字符串();
}
}
公共字符串此[string columnName]
{
得到
{
开关(列名称)
{
案例“发货日期”:
//属性级验证
案例“发票日期”:
//属性级验证
//等等。
}
返回null;
}
}
#端区
}
NotificationObject
实现RaisePropertyChanged
:
公共抽象类NotificationObject:INotifyPropertyChanged
{
#区域INotifyPropertyChanged成员
公共事件属性更改事件处理程序属性更改;
#端区
受保护的虚拟void RaisePropertyChanged(字符串propertyName)
{
PropertyChangedEventHandler处理程序=PropertyChanged;
if(处理程序!=null)
处理程序(这是新的PropertyChangedEventArgs(propertyName));
}
受保护的void RaisePropertyChanged(参数字符串[]propertyNames)
{
if(propertyNames==null)
抛出新ArgumentNullException(“propertyNames”);
foreach(propertyNames中的变量名称)
RaisePropertyChanged(名称);
}