Note that there are some explanatory texts on larger screens.

plurals
  1. POValidationRules not removing error when value is set back to valid value
    primarykey
    data
    text
    <p><strong>INTRODUCTION</strong></p> <p>I have created a <em>DecimalTextBox</em> <code>UserControl</code> that houses some decimal validation I need done, so that I dont need to recreate the validation each time, and can just use the <code>UserControl</code> instead. This validation has properties that need to be bound to, and so I have created <code>DependencyProperties</code> so I can bind to them, according to <a href="http://www.codeproject.com/Articles/18678/Attaching-a-Virtual-Branch-to-the-Logical-Tree-in" rel="nofollow">this article by Josh Smith</a>.</p> <hr> <p><strong>THE PROBLEM</strong></p> <p>The control's validation is behaving strangely. When I type an erroneous value into the <code>TextBox</code>, it shows up as an error. However when I try to change the value back <em>in the code</em> the value shown in the textbox remains unchanged.</p> <p>Here are the steps I perform that cause this error (in this example 1 is an invalid value):</p> <ol> <li>Load the form and the default value is <strong>0</strong>.</li> <li>Enter <strong>1</strong> into the textbox (and the textbox goes <strong>red</strong> due to the validation result being and error)</li> <li><em>In the code</em> I set the property bound to the textbox to <strong>0</strong></li> <li>The form still displays <strong>1</strong> in a <strong>red</strong> textbox</li> </ol> <hr> <p><strong>CODE EXAMPLE</strong></p> <p>I prepaired an example demonstrating the problem, which can be downloaded <a href="https://docs.google.com/open?id=0B9JOiSJxT9vjZDExMWY4MWUtNTc5YS00ZmM0LTlkOGItOGRiNmUwMDE3NGM1" rel="nofollow">here.</a></p> <p>I'll post some of the code here, if you want more let me know.</p> <p><strong>ValidationTestControl's XAML</strong></p> <pre><code>&lt;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"&gt; &lt;Grid&gt; &lt;Grid.RowDefinitions&gt; &lt;RowDefinition&gt;&lt;/RowDefinition&gt; &lt;/Grid.RowDefinitions&gt; &lt;StackPanel Orientation="Horizontal" VerticalAlignment="Center" HorizontalAlignment="Center"&gt; &lt;TextBlock Text="Type 'Banana' here: "&gt;&lt;/TextBlock&gt; &lt;TextBox MinWidth="100"&gt; &lt;TextBox.Text&gt; &lt;Binding ElementName="ValidationTest" Path="Text" UpdateSourceTrigger="PropertyChanged" Mode="TwoWay" ValidatesOnDataErrors="True" ValidatesOnExceptions="True"&gt; &lt;Binding.ValidationRules&gt; &lt;v:NotBananaValidationRule&gt; &lt;v:NotBananaValidationRule.NotWhatBinding&gt; &lt;v:NotBananaBinding x:Name="NotBananaValidationBinding"&gt;&lt;/v:NotBananaBinding&gt; &lt;/v:NotBananaValidationRule.NotWhatBinding&gt; &lt;/v:NotBananaValidationRule&gt; &lt;/Binding.ValidationRules&gt; &lt;/Binding&gt; &lt;/TextBox.Text&gt; &lt;/TextBox&gt; &lt;TextBlock Text=" (the text will give error when = 'Banana')"&gt;&lt;/TextBlock&gt; &lt;/StackPanel&gt; &lt;/Grid&gt; </code></pre> <p></p> <p><strong>ValidationTestControls Code Behind</strong> </p> <p>(yes I know not very MVVM but I felt it was ok for this stand alone control)</p> <pre><code> 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); } } } </code></pre> <p><strong>ValidationRule and FrameWorkElement created for binding</strong></p> <pre><code> 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() { } } </code></pre> <p>Basically what this code does is check if you have typed "Banana" and then returns a validation error. The control exposes dependency properties because I want to be able to bind to them when I use the control. The <code>FrameworkElement</code> <em>NotBananaBinding</em> lets me create dependency properties (because it is a <code>DependencyObject</code> so i can bind stuff for the validation. The ValidationRule has a <em>NotBananaBinding</em> property that stores the dependency property and uses it in the validate method.</p> <p>I know my property names are kinda crappy, sorry. The thing is that the example does a good job of displaying the error. In my haste to make an example I didn't name the variables very well. If you find the code crappy <strong>please download the sample</strong> <a href="https://docs.google.com/open?id=0B9JOiSJxT9vjZDExMWY4MWUtNTc5YS00ZmM0LTlkOGItOGRiNmUwMDE3NGM1" rel="nofollow">here.</a></p> <hr> <p><strong>WHAT I'VE FIGURED OUT SO FAR</strong></p> <p>Basically this problem seems to be caused by the fact that I am <em>not actually changing the value</em>.</p> <p>Even if I call OnPropertyChanged on the property, because the value is not different it doesn't try and reevaluate the Validation.</p> <p>I can obviously change the value to some arbitrary Valid value and then change it to the one I want it to be and it will work, but I was hoping there is some way to get call validation manually, to reevaluate the value and then change it etc. The changing it away and back is kinda messy.</p> <hr> <p><strong>CONCLUSION</strong></p> <p>Am I doing something wrong (perhaps something about the way I implemented the validation and binding from Josh Smiths post) </p> <p>Is this just a c# bug, or is the behavior intended? If so then why?</p> <p>Are there any elegant ways to fix it?</p> <p>u_u</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload