j00hi
j00hi

Reputation: 5931

How to implement (bubbling) validation events for custom WPF control

I have developed a custom WPF control:

public partial class PercentTextbox : UserControl, IDataErrorInfo, INotifyDataErrorInfo

And I put that control inside a UserControl along with some other controls:

<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>

And finally, I use another wrapping UserControl to show the above UserControl as dialog:

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

In the code behind of the latter, I want to subscribe to all validation errors, and disable the save button if there are errors.

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

I was thinking, that if I'd implement IDataErrorInfo or INotifyDataErrorInfo, WPF would somehow magically handle stuff for me, and create a ValidationError event (which would bubble up to the UserControl. But clearly, I am missing something essential here.

My question is: What do I have to implement in my custom control PercentTextbox in order to use it in arbitrary places and still get some kind of bubbling-up validation information which I can use in a container UserControl (e.g. to disable the SaveButton).

Upvotes: 0

Views: 954

Answers (1)

dymanoid
dymanoid

Reputation: 15197

The IDataErrorInfo and INotifyDataErrorInfo are supposed to be implemented on the model side, not on the UI side. Then you can set the ValidatesOnDataErrors = True or ValidatesOnNotifyDataErrors = True options on your Bindings, so that the binding validation system jumps in. There are some good tutorials on the web about that. It's not the UI telling that something is invalid, but the data this UI represents.

The data validation concept is tightly coupled with the data bindings. If you want your user control to perform its own "UI" validation, use the coercing and validation callbacks of the dependency properties. However, this has nothing to do with the data validation of the binding system. The validation callback will cause the property system to throw an exception that you can handle as you wish (e.g. you can use the ExceptionValidationRule for your bindings).

Take a look on the Validation.Error attached event documentation (which you're actually trying to observe by calling Validation.AddErrorHandler). It states:

Occurs when the bound element runs into a validation error, but only for bindings with the NotifyOnValidationError value set to true.

So you have two options now:

  • implement the validation on the model side and set up your bindings accordingly (you have to do this for each binding to your custom control's properties)
  • use the dependency property validation callbacks

Upvotes: 1

Related Questions