如何为自定义WPF控件实现(冒泡)验证事件

时间:2017-07-25 09:09:14

标签: c# wpf validation xaml

我开发了一个自定义WPF控件:

public partial class PercentTextbox : UserControl, IDataErrorInfo, INotifyDataErrorInfo

我将该控件放在UserControl以及其他一些控件中:

<UserControl x:Class="UserControlContainingPercentTextboxAndStuff" DataContext="Something" ...>
  <Grid>
    <mycontrols:PercentTextbox Value="{Binding MyPercentageValue, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, NotifyOnValidationError=True}" ... />
    <TextBox ... />
    <mycontrols:PercentTextbox ... />
    <TextBox ... />
    <TextBox ... />
  </Grid>
</UserControl>

最后,我使用另一个换行UserControl将上面的UserControl显示为对话框:

<UserControl ...>
  <Grid>
    <local:UserControlContainingPercentTextboxAndStuff ... />
    <Button x:Name="SaveButton" Content="Save" ... />
    <Button x:Name="CancelButton" Content="Cancel" ... />
  </Grid>
</UserControl>

在后者的代码中,我想订阅所有验证错误,并在出现错误时禁用保存按钮。

Validation.AddErrorHandler(this, (sender, e) =>
{
  SaveButton.IsEnabled = false;
  Debug.WriteLine(e.Error);
});

我在想,如果我实现IDataErrorInfoINotifyDataErrorInfo,WPF会以某种方式神奇地为我处理内容,并创建一个ValidationError事件(它会冒泡到{{}但是很明显,我在这里缺少必要的东西。

我的问题是:我必须在我的自定义控件UserControl中实现什么才能在任意位置使用它,并且仍然可以获得某种冒泡验证信息,我可以在容器中使用{{1} 1}}(例如,禁用SaveButton)。

1 个答案:

答案 0 :(得分:1)

IDataErrorInfoINotifyDataErrorInfo应该在模型方面实现,而不是在UI方面实现。然后,您可以在ValidatesOnDataErrors = True上设置ValidatesOnNotifyDataErrors = TrueBinding选项,以便绑定验证系统跳入。网上有一些关于此的好教程。它并不是UI告诉某些内容无效,而是此UI所代表的数据。

数据验证概念与数据绑定紧密结合。如果您希望您的用户控件执行自己的&#34; UI&#34;验证,使用依赖项属性的the coercing and validation callbacks。但是,这与绑定系统的数据验证无关。验证回调将导致属性系统抛出您可以根据需要处理的异常(例如,您可以使用ExceptionValidationRule进行绑定)。

查看Validation.Error附加事件documentation(您通过致电Validation.AddErrorHandler实际尝试观察的事件)。它声明:

  

当绑定元素遇到验证错误时发生,但仅限于此   用于绑定NotifyOnValidationError值设置为true

所以你现在有两个选择:

  • 在模型端实现验证并相应地设置绑定(必须为每个绑定到自定义控件的属性执行此操作)
  • 使用依赖项属性验证回调