3

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

Community
  • 1
  • 1

2 Answers2

1

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.

a little sheep
  • 1,416
  • 9
  • 6
  • Interesting. I'll try this out tomorrow. –  Jun 22 '12 at 00:51
  • It worked. Once. Now it isn't working anymore. I need to investigate this further. –  Jun 22 '12 at 13:12
  • Hmmm, I think that was because the value I was validating was the BindingExpression. Need to tweak the ValidationStep. –  Jun 22 '12 at 13:15
  • Okay, going with ConvertedProposedValue it works. Reliably. I wish there was a more direct solution; I kind of consider this a hack. But without reflection I don't see any other alternative right now, and I don't observe any side effects (as of yet) of this method. Accepted! Thanks, and welcome to SO. –  Jun 22 '12 at 13:30
0

The solution for my project was:

        var binding = BindingOperations.GetBindingExpression(textbox, TextBox.TextProperty);

        binding.UpdateSource();
        binding.ValidateWithoutUpdate();
Trivalik
  • 80
  • 7