该死的,这需要一段时间来考虑,但一如既往,......附加行为来救援。
您所看到的本质上是脏状态跟踪。使用 ViewModel 有很多方法可以做到这一点,但由于您不想更改实体,最好的方法是使用行为。
首先从 Xaml 绑定中删除 ValidatesOnDataErrors。为您正在处理的控件创建一个行为(如下所示 TextBox )并在 TextChanged 事件(或您想要的任何事件)中将绑定重置为 确实 验证数据错误。真的很简单。
这样,您的实体不必更改,您的 Xaml 保持相当干净,并且您可以了解自己的行为。
这是行为代码-
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
namespace IDataErrorInfoSample
{
public static class DirtyStateBehaviours
{
public static string GetDirtyBindingProperty(DependencyObject obj)
{
return (string)obj.GetValue(DirtyBindingPropertyProperty);
}
public static void SetDirtyBindingProperty(DependencyObject obj, string value)
{
obj.SetValue(DirtyBindingPropertyProperty, value);
}
// Using a DependencyProperty as the backing store for DirtyBindingProperty. This enables animation, styling, binding, etc...
public static readonly DependencyProperty DirtyBindingPropertyProperty =
DependencyProperty.RegisterAttached("DirtyBindingProperty", typeof(string), typeof(DirtyStateBehaviours),
new PropertyMetadata(new PropertyChangedCallback(Callback)));
public static void Callback(DependencyObject obj,
DependencyPropertyChangedEventArgs args)
{
var textbox = obj as TextBox;
textbox.TextChanged += (o, s) =>
{
Binding b = new Binding(GetDirtyBindingProperty(textbox));
b.ValidatesOnDataErrors = true;
textbox.SetBinding(TextBox.TextProperty, b);
};
}
}
}
Xaml 也非常简单。
<Window x:Class="IDataErrorInfoSample.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:IDataErrorInfoSample"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
Title="MainWindow"
Height="350"
Width="525">
<Window.DataContext>
<local:Person />
</Window.DataContext>
<StackPanel Margin="20">
<TextBox Height="20"
Margin="0,0,0,10"
local:DirtyStateBehaviours.DirtyBindingProperty="Name"
Text="{Binding Path=Name}">
</TextBox>
<Button Content="Go" />
</StackPanel>
HTH,Stimul8d。