Question

I'm trying to understand why calls to BindingExpression.ValidateWithoutUpdate() doesn't actually do what it advertises.

I've got some cranky validation (I've removed the boring details from my sample code; suffice it to say it has to do with WF4 ModelItem limitations) that I have to add to a binding via an attached property (e.g., from code and not in xaml).

    // d is DependencyObject and prop is DependencyProperty
    var binding = BindingOperations.GetBinding(d, prop);
    binding.ValidationRules.Add(new MyDerpyValidatonRule());

Nothing crazy here. But the problem is that validation isn't run the first time the control is shown, so validation errors are not exhibited in the UI.

<TextBox
    Grid.Column="1"
    x:Name="derp"
    Text="{Binding Derp, NotifyOnValidationError=True, 
                         ValidatesOnDataErrors=True}"
    t:MyDerpyValidator.TargetProperty="{x:Static TextBox.TextProperty}" />

Binding looks good, works after the value is changed, but when first shown, I get a frownyface instead of the expected red Border:

enter image description here

Initially, I tried calling ValidateWithoutUpdate after I added the ValidationRule to the Binding. This didn't seem to work. Later, I used the Dispatcher to try and put this call off until the application was all warm and cozy (maybe it didn't validate because the tea hadn't finished brewing yet, hell I dunno)

var exp = BindingOperations.GetBindingExpression(d, prop);
Dispatcher.CurrentDispatcher.BeginInvoke(
    (Action<BindingExpression>)(x =>
    {
        x.ValidateWithoutUpdate();
    }),
    DispatcherPriority.ApplicationIdle,
    exp);

I'm pretty sure this worked once. Once. Never worked again. Might have been an incorrect observation on my part.

Later, I tried all kinds of things to get ValidateWithoutUpdate to actually do something. I even tried calling it from within an event handler that would happen way down the road

public DerpyControl()
{
    InitializeComponent();
    derp.MouseEnter += DERPDAMNYOU;
}

void DERPDAMNYOU(object sender, MouseEventArgs e)
{
    derp.GetBindingExpression(TextBox.TextProperty).ValidateWithoutUpdate();
}

It never friggen works.

What do I need to do to get BindingExpression.ValidateWithoutUpdate() to friggen validate?!?!

Was it helpful?

Solution

Wow, that's some weird behaviour. Looking at some of the validation code with ILSpy it has some checks in the background that determine if validation is required or not, and I was too scared to follow it all the way through, so, I too, just tried some random stuff.

This is the first thing I tried that worked:

In your attached property changed handler, after

binding.ValidationRules.Add(new MyDerpyValidatonRule()); 

add

BindingOperations.ClearBinding(d, prop);
BindingOperations.SetBinding(d, prop, binding);

This must somehow set the internal 'validation requred' flag which forces it to validate.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top