Reputation: 157
I'm trying to create a wpf error validation for a textbox. Looks pretty simple but after days and trying many methods I'm still trying to figure out the proper way to do this.
Here is my code (this is not my real code, just an example):
<TextBox Text="{Binding Model.Name , UpdateSourceTrigger=PropertyChanged, ValidatesOnExceptions=True}"
Style="{StaticResource NameTextBoxStyle}" />
<Style x:Uid="Style_81" x:Key="NameTextBoxStyle}" TargetType="{x:Type TextBox}">
<Style.Triggers>
<Trigger Property="Validation.HasError" Value="True">
<Trigger.Setters>
<Setter Property="ToolTip" Value="{Binding RelativeSource={RelativeSource Self},Path= (Validation.Errors)[0].ErrorContent}"/>
</Trigger.Setters>
</Trigger>
</Style.Triggers>
</Style>
Public Class SomeClass
{
public bool IsNameMandatory { get; set; }
string name;
public string Name
{
get
{
return name;
}
set
{
if (IsNameMandatory && String.IsNullOrEmpty(value))
{
throw new Exception("Name can not be empty.");
}
if (value.Length > 12)
{
throw new Exception("name can not be longer than 12 charectors");
}
name = value;
OnPropertyChanged("Name");
}
}
}
The problem: The error validation is working but when the model is "initialized" and set a blank value to "Name" an exception is raised with a messagebox instead of the red rectangle with the tooltip. I don't want to display the exception in a messagebox.
My needs: I need to validate the error only on LostFocus of the textbox and on demand
Upvotes: 0
Views: 1707
Reputation: 12119
Here is how WPF validation is properly done using Binding.ValidationRules Property:
In your View:
xmlns:tools="clr-namespace:SomeAppNameSpace.Tools"
<TextBox Style="{StaticResource SomeStyle}">
<TextBox.Text>
<Binding Path="SomeProperty" UpdateSourceTrigger="LostFocus" >
<Binding.ValidationRules>
<tools:SomeValidationRule />
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>
ValidationRule class located in your tools (or equivalent of) namespace:
public class SomeValidationRule : ValidationRule
{
public override ValidationResult Validate(object value,
CultureInfo cultureInfo)
{
var userText = value as string;
return String.IsNullOrWhiteSpace(userText) ?
new ValidationResult(false, "Value must be provided.") :
new ValidationResult(true, null);
}
}
So, this simple ValidationRule
checks the textbox on LostFocus
and if the textbox is left empty it returns a validation error message...
Last piece of the puzzle is that your "SomeStyle" which is the style for the textbox above must have Validation.ErrorTemplate
defined... something like this:
<Style x:Key="SomeStyle" TargetType="{x:Type TextBox}">
<Setter Property="Validation.ErrorTemplate">
<Setter.Value>
<ControlTemplate >
<!-- Your Error Template here. Typically a border with
red background and a textbox with light colored text... -->
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Upvotes: 2