Reputation: 3407
I want to validate some Text
in a TextBlock
TextBlock xaml:
<TextBlock x:Name="numInput" Validation.ErrorTemplate="{StaticResource errorTemplate}" >
<TextBlock.Text>
<Binding Path="Text" RelativeSource="{RelativeSource self}" NotifyOnValidationError="True">
<Binding.ValidationRules>
<local: NumberValidator />
</Binding.ValidationRules>
</Binding>
</TextBlock.Text>
</TextBlock>
The Text
is added in codebehind by some button clicks in the GUI (i.e. a touch screen)
errorTemplate
<ControlTemplate x:Key="errorTemplate">
<StackPanel>
<TextBlock Foreground="Red">error msg</TextBlock>
<AdornedElementPlaceholder/>
</StackPanel>
</ControlTemplate>
NumberValidator
class NumberValidator : ValidationRule {
public override ValidationResult Validate(object value, System.Globalization.CultureInfo cultureInfo) {
Console.WriteLine("validating numbers!!");
int num = -1;
try {
num = Int32.Parse(value.ToString());
}
catch (Exception e) {
return new ValidationResult(false, "input must be numbers!");
}
if (num > 999 || num < 1) {
return new ValidationResult(false, string.Format("must be integers from {0} to {1}", 1, 999));
}
return new ValidationResult(true, null);
}
}
Questions:
No error message is shown. In fact, NumberValidator
isn't even called. Why?
How to validate the error only when a Button
is clicked?
How to pass valid range (i.e min, max) information to the NumberValidator
?
Thanks!
Upvotes: 0
Views: 96
Reputation: 10349
I assume that you want to perform validation in source-to-target direction (provide visual feedback for model errors), therefore my answer only applies if this is the case.
Validation rules are by design only checked in target-to-source direction (the main idea here is to validate user input), so when you change the value on the model, validation rules are not checked. In order to perform validation in source-to-target direction, your model should implement either IDataErrorInfo
or INotifyDataErrorInfo
(the latter being supported only in .NET 4.5 or newer), and ValidatesOnDataErrors
should be set to true
on the binding.
The validation occurs whenever binding is updated, so if the button click updates the property on the model (or, more specifically, raises PropertyChanged
event), the validation will be performed. Note that if property is changed on some other occasion, the validation will also be performed, so in order to perform the validation only on button click make sure the property is changed (or PropertyChanged
is raised) only then.
Despite using ValidationRule
derivatives is not appropriate approach in assumed scenario, the answer is to define Max
and Min
properties on the NumberValidator
class, and then use them in XAML like so: <local:NumberValidator Min="0" Max="100"/>
.
For more information on bindings see Data Binding Overview.
Upvotes: 2