我有一个非常简单的 DataGrid 绑定到自定义对象的集合。自定义对象使用 DataAnnotations 进行注释并实现 IDataErrorInfo。
public class MyObject : IDataErrorInfo {
[Required(ErrorMessageResourceName = "Amount_Required", ErrorMessageResourceType = typeof(Resources))]
[Range(typeof(decimal), "0", "1000000000", ErrorMessageResourceName = "InventoryCost_Amount_Invalid", ErrorMessageResourceType = typeof(Resources))]
public decimal? Amount { get; set; }
[Required(ErrorMessageResourceName = "Name_Required", ErrorMessageResourceType = typeof(Resources))]
[StringLength(50, ErrorMessageResourceName = "Name_MaxLength", ErrorMessageResourceType = typeof(Resources))]
public string Name { get; set; }
// standard IDataErrorInfo stuff here
}
我希望 DataGrid 验证其中的任何对象,并且我将能够在代码中检测对象是否正确。我尝试了以下方法:
在 UserControl 中添加所有验证错误的集合
private readonly List<Tuple<object, ValidationError>> errors = new List<Tuple<object, ValidationError>>();
在 UserControl 的构造函数中添加验证处理程序:
Validation.AddErrorHandler(this, ErrorChangedHandler);
处理验证更改:
private void ErrorChangedHandler(object sender, ValidationErrorEventArgs e) { Debug.WriteLine(e.Action.ToString() + ":object=" + e.OriginalSource.ToString() + ",error=" + e.Error.ToString()); if (e.Action == ValidationErrorEventAction.Added) { errors.Add(new Tuple<object, ValidationError>(e.OriginalSource, e.Error)); } else { Tuple<object, ValidationError> error = errors.FirstOrDefault(err => err.Item1 == e.OriginalSource && err.Item2 == e.Error); if (error != null) { errors.Remove(error); } } bool hasError = !errors.Any(); }
如果我编辑现有对象,这可以正常工作,但是如果我尝试添加新对象,错误更改的事件流非常奇怪:TextBlock 的验证错误在创建新对象时添加并且永远不会删除,即使我为所有对象设置了正确的值两个领域。这是我的日志(我记录了所有验证错误):
(I created new row,i.e. object)
添加:object=System.Windows.Controls.TextBlock,error=System.Windows.Controls.ValidationError 添加:object=System.Windows.Controls.TextBlock,error=System.Windows.Controls.ValidationError 添加:object=System.Windows。 Controls.TextBox,error=System.Windows.Controls.ValidationError 已添加:object=System.Windows.Controls.DataGridCell,error=System.Windows.Controls.ValidationError 已删除:object=System.Windows.Controls.DataGridCell,error=System。 Windows.Controls.ValidationError
(I put correct value for Name field)
已删除:object=System.Windows.Controls.TextBox,error=System.Windows.Controls.ValidationError 添加:object=System.Windows.Controls.TextBox,error=System.Windows.Controls.ValidationError 添加:object=System.Windows。 Controls.DataGridCell,error=System.Windows.Controls.ValidationError
(I put correct value for Amount field, now object (and whole row is the grid) is valid)
已删除:object=System.Windows.Controls.DataGridCell,error=System.Windows.Controls.ValidationError 已删除:object=System.Windows.Controls.TextBox,error=System.Windows.Controls.ValidationError
但是与 TextBlock 相关的前两个错误没有被删除,因此所有错误的列表不为空,并且 ErrorChangedHandler 中的 hasError 变量为 false。我的 XAML 也很简单:
<DataGrid x:Name="grid"
ItemsSource="{Binding MyObjects}"
CanUserDeleteRows="False" Margin="11,11,11,11"
AutoGenerateColumns="False"
Height="308">
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding Path=Name, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True,
ValidatesOnExceptions=True, NotifyOnValidationError=True}"
Header="Name" Width="100" ElementStyle="{StaticResource TextCellElementStyle}"
EditingElementStyle="{StaticResource TextCellEditingStyle}"/>
<DataGridTextColumn Binding="{Binding Path=Amount, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True,
ValidatesOnExceptions=True, NotifyOnValidationError=True}"
Header="Amount" Width="75" ElementStyle="{StaticResource TextCellElementStyle}"
EditingElementStyle="{StaticResource TextCellEditingStyle}"/>
</DataGrid.Columns>
</DataGrid>