我有一个非常简单的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)
添加了:对象= System.Windows.Controls.TextBlock,误差= System.Windows.Controls.ValidationError 添加了:对象= System.Windows.Controls.TextBlock,误差= System.Windows.Controls.ValidationError 添加了:对象= System.Windows.Controls.TextBox,误差= System.Windows.Controls.ValidationError 添加了:对象= System.Windows.Controls.DataGridCell,误差= System.Windows.Controls.ValidationError 删除:对象= System.Windows.Controls.DataGridCell,误差= System.Windows.Controls.ValidationError
(I put correct value for Name field)
移除:对象= System.Windows.Controls.TextBox,误差= System.Windows.Controls.ValidationError 添加了:对象= System.Windows.Controls.TextBox,误差= System.Windows.Controls.ValidationError 添加了:对象= System.Windows.Controls.DataGridCell,误差= System.Windows.Controls.ValidationError
(I put correct value for Amount field, now object (and whole row is the grid) is valid)
移除:对象= System.Windows.Controls.DataGridCell,误差= System.Windows.Controls.ValidationError 删除:对象= System.Windows.Controls.TextBox,误差= 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>