关于我是否可以设置绑定以便 WPF 自动测试接口的Error
属性的问题,我在这里IDataErrorInfo
找到了以下否定答案:
某人的问题:
基本上,我想知道一个 Binding 属性会触发 IDataErrorInfo.Error 的测试,就像 ValidatesOnDataErrors 导致 IDataErrorInfo.Item 的测试一样。
来自 Microsoft 在线社区支持的回答:
设置 Binding 类的 ValidatesOnDataErrors 属性仅测试 IDataErrorInfo.Item 而不是 IDataErrorInfo.Error。
到目前为止,Binding 类没有提供一个属性来检查 IDataErrorInfo.Error 作为 ValidatesOnDataErrors 属性来检查 IDataErrorInfo.Item。
为了得到你想要的,我们必须设置一个数据绑定到 IDataError.Error...
因此,该Error
属性没有比CrossPropertyErrors
在域实体中定义我自己的手工属性(如 )更有价值的了。WPF 不支持Error
以简单的内置方式测试属性。
编辑:上面的报价来自 2008 年 3 月,因此很可能与 .NET 3.5 有关。但我找不到任何迹象表明这在 .NET 4.0 中确实发生了变化。
编辑:最后我必须创建自己的手写绑定到Error
属性,并用适当的跨属性错误消息填充它。现在,类中任何其他属性的每次更改都会引发PropertyChanged
更改的属性本身和属性的事件,Error
以刷新 UI 上的错误消息。
编辑 2
它看起来大致是这样的:
模型(或 ViewModel)类:
public class SomeModel : NotificationObject, IDataErrorInfo
{
private string _someProperty;
public string SomeProperty
{
get { return _someProperty; }
set
{
if (_someProperty != value)
{
_someProperty = value;
RaisePropertyChanged("SomeProperty", "Error");
// That's the key: For every changed property a change
// notification also for the Error property is raised
}
}
}
// The above repeats for every property of the model
#region IDataErrorInfo Member
public string Error
{
get
{
var sb = new StringBuilder();
// for example...
if (InvoiceDate < ShippingDate)
sb.AppendLine("InvoiceDate must not be before ShippingDate.");
// more cross-property validations... We have only one Error
// string, therefore we append the messages with
// sb.AppendLine("Another message...") ... etc.
// could all be moved into a separate validation class
// to keep the model class cleaner
return sb.ToString();
}
}
public string this[string columnName]
{
get
{
switch (columnName)
{
case "ShippingDate":
// property-level validations
case "InvoiceDate":
// property-level validations
// etc.
}
return null;
}
}
#endregion
}
NotificationObject
实现RaisePropertyChanged
:
public abstract class NotificationObject : INotifyPropertyChanged
{
#region INotifyPropertyChanged Member
public event PropertyChangedEventHandler PropertyChanged;
#endregion
protected virtual void RaisePropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
handler(this, new PropertyChangedEventArgs(propertyName));
}
protected void RaisePropertyChanged(params string[] propertyNames)
{
if (propertyNames == null)
throw new ArgumentNullException("propertyNames");
foreach (var name in propertyNames)
RaisePropertyChanged(name);
}
// ...
}
然后在一个视图中,该Error
属性被绑定到 - 例如 - a TextBlock
,它显示了跨属性验证错误:
<TextBlock Text="{Binding SomeModel.Error}" TextWrapping="Wrap" ... />
因此:模型上的每个更改的属性都将通知 WPF 绑定引擎有关属性的(潜在)更改,Error
从而导致跨属性验证文本的更新。