如何实现自定义WPF控件
我已经开发了一个自定义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);
});
我在想,如果我实现IDataErrorInfo
或INotifyDataErrorInfo
,WPF会神奇地处理的东西对我来说,并创建一个ValidationError事件(这会泡到UserControl
。但显然,我的思念这里的东西必不可少
我的问题是:怎么我有我的自定义控件PercentTextbox
来实现,以便使用它在任意地方,仍然可以得到某种起泡了验证信息,我可以在一个容器UserControl
使用(例如,禁用SaveButton)
IDataErrorInfo
和INotifyDataErrorInfo
应该在模型端实现,而不是在UI端。然后,您可以在Binding
上设置ValidatesOnDataErrors = True
或ValidatesOnNotifyDataErrors = True
选项,以便绑定验证系统跳入。网上有一些关于此的良好教程。不是用户界面告诉某些东西无效,而是用户界面代表的数据。
数据验证概念与数据绑定紧密结合。如果您希望用户控件执行自己的“UI”验证,请使用依赖项属性的the coercing and validation callbacks。但是,这与绑定系统的数据验证无关。验证回调会导致属性系统抛出异常,您可以根据需要处理异常(例如,您可以使用ExceptionValidationRule
作为绑定)。
看一看Validation.Error
附加事件documentation(你实际上试图通过调用Validation.AddErrorHandler
来观察)。它指出:
当绑定元素运行到验证错误,但只发生 与设置为true的NotifyOnValidationError值绑定。
所以你现在两个选择:
- 落实在模型方面的验证,并相应地设置您的绑定(你必须为每一个绑定到自定义控件的属性做到这一点)
- 使用依赖属性验证回调