ValidationRules does not remove the error when the value returns to the actual value

Introduction

I created a DecimalTextBox UserControl that stores some decimal check that I need to do, so I don’t need to recreate the check every time, and I can just use UserControl . This check has properties that you need to bind to, and so I created DependencyProperties , so I can bind to them, according to this article by Josh Smith .


PROBLEM

The verification check behaves strangely. When I enter an erroneous value in a TextBox , it displays as an error. However, when I try to change the value back in the code, the value displayed in the text box remains unchanged.

Here are the steps I follow that cause this error (in this example, 1 is an invalid value):

  • Download the form and the default value is 0 .
  • Enter 1 in the text box (and the text box goes red due to the result of the check and error)
  • In the code, I set the property associated with the text box to 0
  • The form is still displayed 1 in the red text box

CODE EXAMPLE

I prepared an example demonstrating a problem that can be downloaded here.

I will write part of the code here if you want to tell me more.

ValidationTestControl XAML

 <UserControl x:Class="WPFTestProject.ValidationTestControl" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:v="clr-namespace:WPFTestProject" x:Name="ValidationTest" Height="50" Width="525"> <Grid> <Grid.RowDefinitions> <RowDefinition></RowDefinition> </Grid.RowDefinitions> <StackPanel Orientation="Horizontal" VerticalAlignment="Center" HorizontalAlignment="Center"> <TextBlock Text="Type 'Banana' here: "></TextBlock> <TextBox MinWidth="100"> <TextBox.Text> <Binding ElementName="ValidationTest" Path="Text" UpdateSourceTrigger="PropertyChanged" Mode="TwoWay" ValidatesOnDataErrors="True" ValidatesOnExceptions="True"> <Binding.ValidationRules> <v:NotBananaValidationRule> <v:NotBananaValidationRule.NotWhatBinding> <v:NotBananaBinding x:Name="NotBananaValidationBinding"></v:NotBananaBinding> </v:NotBananaValidationRule.NotWhatBinding> </v:NotBananaValidationRule> </Binding.ValidationRules> </Binding> </TextBox.Text> </TextBox> <TextBlock Text=" (the text will give error when = 'Banana')"></TextBlock> </StackPanel> </Grid> 

ValidationTestControls Code Behind

(yes, I do not know very MVVM, but I felt that it was normal for this autonomous control)

  public partial class ValidationTestControl : UserControl { public ValidationTestControl() { InitializeComponent(); Banana = "Banana"; Binding BananaBinding = new Binding("Banana"); BananaBinding.Source = this; NotBananaValidationBinding.SetBinding(NotBananaBinding.NotWhatProperty, BananaBinding); } public static DependencyProperty TextProperty = DependencyProperty.Register("Text", typeof(string), typeof(ValidationTestControl), new PropertyMetadata()); public static DependencyProperty BananaProperty = DependencyProperty.Register("Banana", typeof(string), typeof(ValidationTestControl), new PropertyMetadata()); public string Text { get { return (string)GetValue(TextProperty); } set { SetValue(TextProperty, value); } } public string Banana { get { return (string)GetValue(BananaProperty); } set { SetValue(BananaProperty, value); } } } 

ValidationRule and FrameWorkElement are for binding

  public class NotBananaValidationRule:ValidationRule { private NotBananaBinding _notWhatBinding; public NotBananaBinding NotWhatBinding { get { return _notWhatBinding; } set { _notWhatBinding = value; } } public override ValidationResult Validate(object value, System.Globalization.CultureInfo cultureInfo) { string what = value.ToString(); if(what == _notWhatBinding.NotWhat||string.IsNullOrEmpty(what)) return new ValidationResult(false, "Please enter a string that is not " + _notWhatBinding.NotWhat); else return new ValidationResult(true, null); } } public class NotBananaBinding : FrameworkElement { public static readonly DependencyProperty NotWhatProperty = DependencyProperty.Register( "NotWhat", typeof(string), typeof(NotBananaBinding), new UIPropertyMetadata()); public string NotWhat { get { return (string)GetValue(NotWhatProperty); } set { SetValue(NotWhatProperty, value); } } public NotBananaBinding() { } } 

Basically what this code does, check to see if you typed β€œBanana” and then returned a validation error. The control provides dependency properties because I want to be able to bind to them when using the control. FrameworkElement NotBananaBinding allows me to create dependency properties (because it is a DependencyObject , so I can bind the material for validation. ValidationRule has a NotBananaBinding property that saves the dependency property and uses it in the validation method.

I know my property names are a little crappy, sorry. The fact is that in this example, a good job is to display the error. In my haste to give an example, I did not name the variables very well. If you find crappy code , download the sample here.


WHAT I PICTURE SOON

Basically this problem is apparently caused by the fact that I actually do not change the value.

Even if I call OnPropertyChanged in the property because the value is not different, it does not try and does not overestimate the check.

I can obviously change the value to some arbitrary Valid value and then change it to the one I want and it will work, but I was hoping there was a way to get the validation manually, re-evaluate the value and then change it and etc. Changing it back and forth will be messy.


Conclusion

I'm doing something wrong (maybe something about how I applied validation and binding to Josh Smith's post)

Is this just a C # error, or is this behavior? If so, why?

Are there any elegant ways to fix this?

u_u

+4
source share
1 answer

Validation does not allow setting the Text property. Place a breakpoint on the setter and you will see that it does not break when you enter the last "a". If you type Bananan and click Backspace and its errors, click the button and it will work. Validation ensures that your property may have an invalid value. Therefore, if you save it to report the database while in error, it will not save the invalid value.

+1
source

Source: https://habr.com/ru/post/1397407/


All Articles