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