In my current projet, I have to deal with data validation in a WPF form. My form is in a DataTemplate in a ResourceDictionnary. I can save and load the data from my form thanks to two buttons, which serialize and deserialize the data (through two DelegateCommand).
If one field of my form is empty or invalid, the save button is disable. A field is checked everytime it changes thanks to the UpdateSourceTrigger propertie. That's why I need to know in my C# code if a field is invalid to update my save command.
Currently, I use the ExceptionValidationRule in my XAML Binding and I wonder if it's a good pratice. I can't implement a ValidationRule because I need to know in my C# code if a field is invalid, to update the save command (enable or disable the save button).
<TextBox>
<Binding Path="Contact.FirstName" UpdateSourceTrigger="PropertyChanged">
<Binding.ValidationRules>
<ExceptionValidationRule/>
</Binding.ValidationRules>
</Binding>
</TextBox>
In this blog, we can read :
Raising exceptions in the Setters is not a very good approach since those properties are also set by code and sometimes it is ok to temporarily leave them with error values.
I already read this post but I can't use it, my TextBox are in a DataTemplate and I can't use them in my C# code.
So, I wonder if I should change my Data Validation and don't use the ExceptionValidationRule.
Thank you blindmeis, your idea was good. IDataErrorInfo seems to be better than the ExceptionValidationException and it works.
Here is an example which match my project : IDataErrorInfo sample
It doesn't use the DelegateCommand but is simple enough to be modified. Your model has to implement IDataErrorInfo :
public class Contact : IDataErrorInfo
{
public string Error
{
get { throw new NotImplementedException(); }
}
public string Name { get; set; }
public string this[string property]
{
get
{
string result = null;
if (property== "Name")
{
if (string.IsNullOrEmpty(Name) || Name.Length < 3)
result = "Please enter a Name";
}
return result;
}
}
}
In the XAML code, don't forget to change the Binding :
<TextBox>
<Binding Path="Contact.Name" UpdateSourceTrigger="PropertyChanged" ValidatesOnDataErrors="True" NotifyOnValidationError="True"/>
</TextBox>