I have the same question as in the link below, but the answers where not satisfying for me.
ValidationRule ValidatesOnTargetUpdated NullReferenceException at Design Time
XAML
<TextBox x:Name="MyTextBox">
<TextBox.Text>
<Binding Path="MyText">
</Binding>
</TextBox.Text>
</TextBox>
Code-Behind
Binding binding = BindingOperations.GetBinding(MyTextBox, TextBox.TextProperty);
binding?.ValidationRules.Add(new MyValidationRule()
{
ValidatesOnTargetUpdated = true
});
It works with this section in code behind. But I am looking for a only XAML solution, because it is more intuitive and for me better maintainable. Does anybody have an idea?
I found a "solution" (or more a workaround) on my own. The designer works for me if I change ValidatesOnTargetUpdated to ValidationStep with the wished value.
Attention: For example, the TextBox behaves differently if you put in ValidationStep="UpdatedValue" and ValidationStep="ConvertedProposedValue". More information on ValidationRule with ValidationStep="UpdatedValue" is called with BindingExpression instead of updated value.
However, I could not find why ValidatesOnTargetUpdated did not work.
Related
I'm using a PasswordBox which exposes a dependency property such that I can bind to it. The problem is that by using it like so, I cannot shorthand the Binding.ValidationRules to this syntax:
<PasswordBox services:RPLPasswordBoxBinder.BindPassword="True"
services:RPLPasswordBoxBinder.BoundPassword="{Binding Path=LoginUser.Parola, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
</PasswordBox>
I set my ValidationRules to a textbox like this:
<TextBox.Text>
<Binding Path="LoginUser.Parola" UpdateSourceTrigger="PropertyChanged">
<Binding.ValidationRules>
<some validation rule/>
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
Is there any way to specify the ValidationRules collection to my PasswordBox in a single xaml line? Or maybe there's another clever solution for validating user input into my password box?
Some clarifications:
I'm using MVVM and I don't want to use code behind.
I want to add only a single ValidationRule. Maybe the problem with shorthanding Binding.ValidationRules is that this property is a collection. One validationrule would suffice in my situation.
There's a similar question on stackoverflow here. My problem is different as I don't just want to increase readability but actually validate my PasswordBox.
I suggest that you base your data model class on IDataErrorInfo and then validation is performed there and not in the code behind.
There are plenty of examples, but here's one for starters and another here.
I created a class IntegersValidationRule which inherits from ValidationRule. Now I don't know what code should I write in XAML. That's what I have:
<TextBox Name="defaultTxt"
Height="23" Width="200">
<TextBox.Text>
<Binding UpdateSourceTrigger="PropertyChanged">
<Binding.ValidationRules>
<what:IntegersValidationRule/>
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>
I know that either I'm so stupid that I can't understand in many tutorials what Path in Binding property means, why should we use Binding here when there's no binding required and what should I use instead of 'what' word inside Binding.ValidationRule.
what is an xmlns (see MSDN) which needs to point to the namespace in which your validation rule class is declared, e.g.
xmlns:what="clr-namespace:MyApp.MyValidationRules"
If you add no Path (- how about reading this if you do not understand it? -) the binding will bind to the current DataContext, whatever that may be in your case.
Question 1: validators work on bindings. That is why you specify the rule on a binding. As soon as then value will be updated to the source (object that the control binds to) the rule is checked.
Question 2: See H.B. 's answer
I've run across the need to apply the ExceptionValidationRule to many textboxes on a form in WPF. I can do this with markup and I get the desired result (the textbox gets a red outline when an invalid value is entered) but only when I supply the rule in markup:
<TextBox x:Name="Name" Width="150" >
<TextBox.Text>
<Binding Path="Name" Mode="TwoWay" UpdateSourceTrigger="PropertyChanged" NotifyOnValidationError="True">
<Binding.ValidationRules>
<ExceptionValidationRule />
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>
But when I apply the value using code:
Name.GetBindingExpression(TextBox.TextProperty).ParentBinding.ValidationRules.Add(new ExceptionValidationRule());
I don't get the desired results. This code is applied in a userControl's constructor after the InitalizeComponent() call. The user control has the textbox "Name" as a child control.
I've gone through and I can see, when using both, that two validation rules are put in the ValidationRules collection but when I am using just the code version I don't get the desired result of a red outline around the textbox when an invalid value is entered.
Am I just misunderstanding a fundamental rule to WPF?
Or, is there a way I can apply this validation rule using a Style? I'd prefer that, to tell you the truth.
Thanks,
M
You can't change a Binding after it has been used, and apperently that goes for the ValidationRules as well. You can create a new Binding in code but that's probably not what you're after.
Binding binding = new Binding("Name");
binding.Mode = BindingMode.TwoWay;
binding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
binding.NotifyOnValidationError = true;
binding.ValidationRules.Add(new ExceptionValidationRule());
nameTextBox.SetBinding(TextBox.TextProperty, binding);
A Style won't work either since a Binding or ValidationRule doesn't derive from FrameworkElement. What I would do in your situation is a subclassed Binding where you add all the things you need. Something like this
<TextBox x:Name="Name" Width="150" >
<TextBox.Text>
<local:ExBinding Path="Name"
Mode="TwoWay"
UpdateSourceTrigger="PropertyChanged"/>
</TextBox.Text>
</TextBox>
The ExBinding, adding ValidationRule etc.
public class ExBinding : Binding
{
public ExBinding()
: base()
{
NotifyOnValidationError = true;
ValidationRules.Add(new ExceptionValidationRule());
}
}
I have a textbox that has a ValidationRule applied to it:
<TextBox Style="{StaticResource StandardTextBox}"
Grid.Column="1" Grid.Row="4"
IsReadOnly="{Binding SaveModeText}"
MaxLength="50">
<TextBox.Text>
<Binding Path="Individual.SurName"
UpdateSourceTrigger="PropertyChanged"
ValidatesOnDataErrors="True"
ValidatesOnExceptions="True"
NotifyOnValidationError="True">
<Binding.ValidationRules>
<valid:RequiredTextBoxValidationRule
ErrorMessage="Please enter a last name" />
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>
When the page loads the textbox contains the correct value based on its binding. If I delete the value from the textbox the ValidationRule fires properly and I see the error message as expected. My application contains a "Discard Changes" button which reloads the DataContext. The hope was it would reset all of the bindings and once again this textbox would display the original value. For some reason, all other values on the page that do not have a ValidationRule associated with them get reset properly, but this textbox does not.
If I remove the ValidationRule from the XAML the value resets properly. If I handle validation through IDataErrorInfo, the validation fires properly and the value resets properly. Because I have used ValidationRules throughout my application, I was wondering if anyone had come across this issue and resolved it. At this point I would prefer to stick with the implemented ValidationRules if possible, instead of switching everything over to IDataErrorInfo.
Since your you are modifying the value in code, wouldn't you need to have Mode=TwoWay in your binding for it to update? I don't have time to dig in and see if that's what's wrong, but it may be a place to start.
I seem to have a problem with TwoWay DataBinding - my application has a window with a bunch of textboxes that allow to edit values of the properties they are bound to. Everything works well except for textboxes that also have a validation rule defined, in which case no text is displayed in the textbox when the window opens (binding back-to-source still works fine for those). If I remove Validation rule, everything's back to normal. I searched for an answer to this for a few hours now, but somehow did not even find anyone else complaining of the same issue. I am completely new to WPF, and I am sure it is just a silly mistake I have somewhere in my code... I will greatly appreciate any feedback...
<TextBox Margin="40,2,20,0" Grid.Column="0" Grid.Row="1" Background="#99FFFFFF" >
<Binding Path="LastName" Mode="TwoWay" ValidatesOnDataErrors="true" UpdateSourceTrigger="LostFocus" >
<Binding.ValidationRules>
<validation:StringNameValidationRule />
</Binding.ValidationRules>
</Binding>
</TextBox>
It would be nice to know what your binding source is, does it implement INotifyPropertyChanged for example?
Without nothing that, the only thing I can think of is the NotifyOnValidationError property on the binding class. Try setting it to true.