ValidationRule Red Border Issue - wpf

In my WPF Application, I have created ValidationRules for my TextBoxes so that it will not allow an empty string which works fine and shows a red border with text telling the user it can not be empty. When the application launches, all the fields are blank waiting for input but I still see the red border around them. Is this normal behavior? Note: I would prefer it firing after either a propertychange event or lostfocus event fires when the user using the form not when the form initially loads.
Example of the validation I am doing:
<TextBox x:Name="itemNum" HorizontalAlignment="Left" Height="23" Margin="82,58,0,0" VerticalAlignment="Top" Width="90"
HorizontalContentAlignment="Left" VerticalContentAlignment="Center" PreviewKeyDown="ItemNum_PreviewKeyDown"
PreviewTextInput="ItemNum_PreviewTextInput" TabIndex="0" Validation.ErrorTemplate="{StaticResource validationErrorTemplate}">
<TextBox.Text>
<Binding Path="rxID" Mode="TwoWay" StringFormat="{}{0:#}" UpdateSourceTrigger="PropertyChanged">
<Binding.ValidationRules>
<MY:TextBoxNotEmptyValidationRule x:Name="rxIDValidation" ValidatesOnTargetUpdated="True" />
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>
My TextBoxNotEmptyValidationRule Class:
public override ValidationResult Validate(object value, System.Globalization.CultureInfo cultureInfo)
{
string str = value as string;
if (string.IsNullOrEmpty(str))
{
return new ValidationResult(false, "Value CAN NOT BE empty");
}
return ValidationResult.ValidResult;
}

According to your logic, it seems that it is normal. Lets define a bool flag and set it false or true, does not matter, than when application is run and check the flag, if flag value is initial value do not do anything. Beside this, you "if" check needs to check also focused element. If focused element is our textbox and your flag is not initial value so you can change the textblock border.

You can look at the following link :
Validation on Load
Ideally this is the normal behavior in XAML applications if you use IDataErorInfo or INotifyDataErrorInfo . you can use beginInit and EndInit to achieve your desired output.

Related

validation not fired unless you type

I have three textbox in a WPF window with UpdateSourceTrigger="LostFocus".
I have also a validation class (:ValidationRule) that return false or true based on my condition, and to keep it so simple: the condition is to check if the string is empty or not.
<TextBox x:Name="TestBox">
<TextBox.Text>
<Binding ElementName="This" Path="test"
UpdateSourceTrigger="LostFocus">
<Binding.ValidationRules>
<local:IPv4ValidationRule />
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>
<TextBlock Margin="2" Foreground="Red" FontWeight="Bold"
Text="{Binding ElementName=TestBox,
Path=(Validation.Errors),
Converter={StaticResource eToMConverter}}" />
the problem is:
if you run the application, and you go through textboxs, no error will be shown on lost focus. I put a button to fire the validation in code, and no error is shown.
ONLY if you type in the textbox, and then clear it, the validation will work.
how can I solve this? because in this case, I cannot confirm if someone leave a textbox empty unless he type in and then delete.
Reading on MSDN, you can find that:
Validation usually occurs when the value of a target is transferred to
the binding source property.
So your validation rule will not be evaluated without typing a key, unless you update the source.
You can do it in you code behind. Supposing that MainWindow is your window, you need to add a Loaded event handler:
public MainWindow()
{
InitializeComponent();
Loaded += new RoutedEventHandler(MainWindow_Loaded);
}
private void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
BindingExpression bindingExpression = TestBox.GetBindingExpression(TextBox.TextProperty);
bindingExpression.UpdateSource();
}
As you can see, the handler's code updates the source, therefore the ValidationRule is evaluated.

Textbox Binding to a double property returns Error Message when entering not a number value in MVVM

I have a TextBox binding to a double property. Here is the xaml
<TextBox Grid.Column="1"
HorizontalAlignment="Stretch"
Margin="0,0,0,15"
Name="textBox_algorthWheight"
VerticalAlignment="Center">
<TextBox.Text>
<Binding Path="AlgorithmWeight" StringFormat="N1">
<Binding.ValidationRules>
<ExceptionValidationRule/>
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>
The property Code as shown below
public double AlgorithmWeight
{
get { return _algorithmWeight; }
set
{
if (value < 1.0)
{
value = 1.0;
}
_algorithmWeight = value;
OnPropertyChanged("AlgorithmWeight");
}
}
MVVM WPF will take care of the exception when I do enter a non number value it will highlight the textbox in red colour which is good but I really want to add an error message next to the text box to notify the user the value is not acceptable, and I will use the previous value or a default value.
Thank you in advance
You should implement IDataErrorInfo. See here for a tutorial, this will show you how to create the message and style your textbox when an error is present:
Link

WPF TextBox Red Border Still Displayed After ValidationRule succeeds

I have a textbox with a very simple ValidationRule:
<TextBox x:Name="textFirstName" Width="120">
<TextBox.Text>
<Binding
Path="CurrentSelectionData.Tables[cpeople].Rows[0][FirstName]"
UpdateSourceTrigger="PropertyChanged">
<Binding.ValidationRules>
<local:NonEmptyStringValidationRule ValidatesOnTargetUpdated="True"/>
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>
public class NonEmptyStringValidationRule : ValidationRule
{
public override ValidationResult Validate(object value, System.Globalization.CultureInfo cultureInfo)
{
if (value == null || string.IsNullOrWhiteSpace(value.ToString()))
return new ValidationResult(false, "Must provide a value.");
return ValidationResult.ValidResult;
}
}
The problem is that the red validation error border displays on start-up even though the textbox is bound to non-empty data.
Watching a breakpoint on the validation rule, I see that it is called once for an empty string (before the binding is changed to valid data) and once again after the binding updates to valid data. Sure enough, the second call returns ValidResult, yet the red border remains.
Manually clearing the textbox and typing new text into it clears the red border, but simply typing new text into it without first clearing it does not.
The one potential trickiness I can see, from reading other folks' questions, is that this TextBox is in a tab control. However, my problem is the opposite of those other folks (they weren't getting a red border despite a failed validation), nor am I moving to a different tab control at any point (which was the cause of the other issues).
Any ideas what I'm missing here?
It turns out that changing validated bound data during a Window's Loaded event caused the problem. In my case, the problem was solved by performing the data change during Initialized or ContentRendered instead. Initialized has the advantage of happening before the first (invalid) binding, thus avoiding a temporary red border to flash up during app load.
I tried to replicate your issue but it seems to work ok in my tests, so the problem must be with the data you are binding to as you said the validationRule is working fine.
Is the Table your binding to TwoWay?
My Test:
xaml:
<TextBox x:Name="textFirstName" Width="120" ToolTip="{Binding RelativeSource={RelativeSource Self}, Path=(Validation.Errors)[0].ErrorContent}">
<TextBox.Text>
<Binding ElementName="UI" Path="TextTest" UpdateSourceTrigger="PropertyChanged" ValidatesOnDataErrors="True" >
<Binding.ValidationRules>
<local:NonEmptyStringValidationRule ValidatesOnTargetUpdated="True" />
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>
code:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private string _textTest;
public string TextTest
{
get { return _textTest ; }
set { _textTest = value; }
}
}
public class NonEmptyStringValidationRule : ValidationRule
{
public override ValidationResult Validate(object value, CultureInfo cultureInfo)
{
return (value is string && !string.IsNullOrEmpty(value.ToString()))
? new ValidationResult(true, null)
: new ValidationResult(false, "Invalid Text");
}
}

WPF: Initializing a TextBox and binding it to a validation rule

I try to validate the IP-Address a user enters into a text box of a WPF Dialog. The text box is supposed to be initialized with 127.0.0.1. This is the XAML:
<TextBox
Height="23"
Width="98"
VerticalAlignment="Top"
HorizontalAlignment="Left"
Name="ip_address"
Text="127.0.0.1">
<TextBox.Text>
<Binding Path="Left" UpdateSourceTrigger="PropertyChanged">
<Binding.ValidationRules>
<local:IPValidationRule />
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>
This attempt to bind the text box to the validation rule causes an error, because the attribute Text already has the value 127.0.0.1. My question is this: How can I achieve initializing and binding simultaneously?
Regards, RSel
PS: Initializing the text box in Window_Loaded doesn't work either. The box just remains empty. Without the binding to the rule it works.
A couple options:
Set an initial value in the property that the textbox is bound to. The binding should pick this up when the control loads. I'm not sure if this meets your goals though.
Use the TargetNullValue property of the binding object to specify what to show when the source is null.
Here's MSDN on option 2:
http://msdn.microsoft.com/en-us/library/system.windows.data.bindingbase.targetnullvalue.aspx

WPF Textbox Binding not Responding when ValidationRule Fired

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.

Resources