我的视图模型基类最初实现了 INotifyDataErrorInfo,并且一切都完美无缺,但我现在正在探索如何使用组合而不是继承来进行验证,以便我的视图模型基类除了 INotifyPropertyChanged 之外不需要做任何事情。我也在寻找一个可重用的解决方案,这样我就不必在我的所有视图模型上实现 INotifyDataErrorInfo。
我创建了 INotifyDataErrorInfo 的具体实现,可以将其包含在需要验证的视图模型中(仅包含相关代码):
public class NotifyDataErrorInfo : INotifyDataErrorInfo
{
public readonly Dictionary<string, string> ValidationErrorsByPropertyName = new Dictionary<string, string>();
public IEnumerable GetErrors(string propertyName)
{
...
}
public bool HasErrors { get; }
public event EventHandler<DataErrorsChangedEventArgs> ErrorsChanged;
}
当 MyViewModel 出现验证错误时,它会通过 NotifyDataErrorInfo 对象的实例获取/设置它们。(在我的原始版本中,ViewModel 实现了 INotifyDataErrorInfo。当我探索通过组合实现相同结果时,情况已不再如此。)
public class MyViewModel : ViewModel
{
public NotifyDataErrorInfo NotifyDataErrorInfo { get; } = new NotifyDataErrorInfo();
}
这是一个文本框,它在 MaxDaysText 属性设置器上报告验证错误,并设置验证错误模板。
<TextBox
Text="{Binding MaxDaysText, UpdateSourceTrigger=PropertyChanged}"
Validation.ErrorTemplate="{StaticResource TextBoxValidationErrorTemplate}" />
我现在需要更新我的验证错误模板以访问 NotifyDataErrorInfo 属性中的错误,但我不确定如何执行此操作。
<ControlTemplate x:Key="TextBoxValidationErrorTemplate">
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Border
Grid.Row="0"
HorizontalAlignment="Left"
BorderBrush="{StaticResource ErrorMessageBorderBrush}"
BorderThickness="1">
<AdornedElementPlaceholder x:Name="_adornedElementPlaceholder" />
</Border>
<ItemsControl
Grid.Row="1"
ItemsSource="{Binding}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBox
Style="{StaticResource ErrorMessageStyle}"
Text="{Binding Path=ErrorContent, Mode=OneWay}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
</ControlTemplate>
我尝试更改所有绑定以查找 NotifyDataErrorInfo,但没有运气。我需要对模板进行哪些更改才能访问 MyViewModel 的 NotifyDataErrorInfo 属性上的验证错误?
编辑: 似乎在组合方法中,ErrorsChanged 始终为空,并且永远不会通知视图。我猜当视图模型本身实现 INotifyDataErrorInfo 时,框架使用 ErrorsChangedEventManager 分配委托。但现在我把它排除在外了。因此,组合似乎不适用于这种方法。这个评价正确吗?