.net 未对WPF DataGrid中的TextBlock调用Validation.ErrorChangedHandler

.net 未对WPF DataGrid中的TextBlock调用Validation.ErrorChangedHandler,.net,wpf,validation,datagrid,.net,Wpf,Validation,Datagrid,我有一个相当简单的DataGrid绑定到一组自定义对象。自定义对象使用DataAnnotations进行注释,并实现IDataErrorInfo public class MyObject : IDataErrorInfo { [Required(ErrorMessageResourceName = "Amount_Required", ErrorMessageResourceType = typeof(Resources))] [Range(typeof(decimal), "

我有一个相当简单的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>>();
    
  • 已更改句柄验证:

    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();
    }
    
    添加:object=System.Windows.Controls.TextBlock,错误=System.Windows.Controls.ValidationError 添加:object=System.Windows.Controls.TextBlock,错误=System.Windows.Controls.ValidationError 添加:object=System.Windows.Controls.TextBox,错误=System.Windows.Controls.ValidationError 添加:object=System.Windows.Controls.DataGridCell,错误=System.Windows.Controls.ValidationError 删除:object=System.Windows.Controls.DataGridCell,错误=System.Windows.Controls.ValidationError

    (I put correct value for Name field)
    
    (I put correct value for Amount field, now object (and whole row is the grid) is valid)
    
    删除:object=System.Windows.Controls.TextBox,错误=System.Windows.Controls.ValidationError 添加:object=System.Windows.Controls.TextBox,错误=System.Windows.Controls.ValidationError 添加:object=System.Windows.Controls.DataGridCell,错误=System.Windows.Controls.ValidationError

    (I put correct value for Name field)
    
    (I put correct value for Amount field, now object (and whole row is the grid) is valid)
    
    删除:object=System.Windows.Controls.DataGridCell,错误=System.Windows.Controls.ValidationError 删除:object=System.Windows.Controls.TextBox,错误=System.Windows.Controls.ValidationError

    (I put correct value for Name field)
    
    (I put correct value for Amount field, now object (and whole row is the grid) is valid)
    
    但和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>