2017-07-25 224 views
0

我已经开发了一个自定义WPF控件(冒泡)验证事件:如何实现自定义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。但显然,我的思念这里的东西必不可少

我的问题是:怎么我有我的自定义控件PercentTextbox来实现,以便使用它在任意地方,仍然可以得到某种起泡了验证信息,我可以在一个容器UserControl使用(例如,禁用SaveButton)

回答

1

IDataErrorInfoINotifyDataErrorInfo应该在模型端实现,而不是在UI端。然后,您可以在Binding上设置ValidatesOnDataErrors = TrueValidatesOnNotifyDataErrors = True选项,以便绑定验证系统跳入。网上有一些关于此的良好教程。不是用户界面告诉某些东西无效,而是用户界面代表的数据。

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

看一看Validation.Error附加事件documentation(你实际上试图通过调用Validation.AddErrorHandler来观察)。它指出:

当绑定元素运行到验证错误,但只发生 与设置为true的NotifyOnValidationError值绑定。

所以你现在两个选择:

  • 落实在模型方面的验证,并相应地设置您的绑定(你必须为每一个绑定到自定义控件的属性做到这一点)
  • 使用依赖属性验证回调