对于 MVVM,我更喜欢将附加属性用于此类事物,因为它们是可重用的,并且可以保持视图模型的清洁。
为了将 Validation.HasError 属性绑定到您的视图模型,您必须创建一个附加属性,该属性具有 CoerceValueCallback,该属性将您的附加属性的值与您正在验证用户输入的控件上的 Validation.HasError 属性同步。
本文解释了如何使用这种技术来解决通知视图模型 WPF ValidationRule 错误的问题。代码在 VB 中,所以如果您不是 VB 人员,我将其移植到 C#。
附加属性
public static class ValidationBehavior
{
#region Attached Properties
public static readonly DependencyProperty HasErrorProperty = DependencyProperty.RegisterAttached(
"HasError",
typeof(bool),
typeof(ValidationBehavior),
new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, null, CoerceHasError));
private static readonly DependencyProperty HasErrorDescriptorProperty = DependencyProperty.RegisterAttached(
"HasErrorDescriptor",
typeof(DependencyPropertyDescriptor),
typeof(ValidationBehavior));
#endregion
private static DependencyPropertyDescriptor GetHasErrorDescriptor(DependencyObject d)
{
return (DependencyPropertyDescriptor)d.GetValue(HasErrorDescriptorProperty);
}
private static void SetHasErrorDescriptor(DependencyObject d, DependencyPropertyDescriptor value)
{
d.SetValue(HasErrorDescriptorProperty, value);
}
#region Attached Property Getters and setters
public static bool GetHasError(DependencyObject d)
{
return (bool)d.GetValue(HasErrorProperty);
}
public static void SetHasError(DependencyObject d, bool value)
{
d.SetValue(HasErrorProperty, value);
}
#endregion
#region CallBacks
private static object CoerceHasError(DependencyObject d, object baseValue)
{
var result = (bool)baseValue;
if (BindingOperations.IsDataBound(d, HasErrorProperty))
{
if (GetHasErrorDescriptor(d) == null)
{
var desc = DependencyPropertyDescriptor.FromProperty(System.Windows.Controls.Validation.HasErrorProperty, d.GetType());
desc.AddValueChanged(d, OnHasErrorChanged);
SetHasErrorDescriptor(d, desc);
result = System.Windows.Controls.Validation.GetHasError(d);
}
}
else
{
if (GetHasErrorDescriptor(d) != null)
{
var desc = GetHasErrorDescriptor(d);
desc.RemoveValueChanged(d, OnHasErrorChanged);
SetHasErrorDescriptor(d, null);
}
}
return result;
}
private static void OnHasErrorChanged(object sender, EventArgs e)
{
var d = sender as DependencyObject;
if (d != null)
{
d.SetValue(HasErrorProperty, d.GetValue(System.Windows.Controls.Validation.HasErrorProperty));
}
}
#endregion
}
在 XAML 中使用附加属性
<Window
x:Class="MySolution.MyProject.MainWindow"
xmlns:v="clr-namespace:MyNamespace;assembly=MyAssembly">
<TextBox
v:ValidationBehavior.HasError="{Binding MyPropertyOnMyViewModel}">
<TextBox.Text>
<Binding
Path="ValidationText"
UpdateSourceTrigger="PropertyChanged">
<Binding.ValidationRules>
<v:SomeValidationRuleInMyNamespace/>
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>
</ Window >
现在,您的视图模型上的属性将与您的文本框上的 Validation.HasError 同步。