2017-07-25 223 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值綁定。

所以你現在兩個選擇:

  • 落實在模型方面的驗證,並相應地設置您的綁定(你必須爲每一個綁定到自定義控件的屬性做到這一點)
  • 使用依賴屬性驗證回調