I've just started adding some validation to a WPF MVVM project. Validation in this paradigm is new to me, but it seems fairly straightforward:
public partial class Price : IDataErrorInfo
{
public double Cost { get; set; }
public string Error
{
get { throw new NotImplementedException(); }
}
string IDataErrorInfo.this[string columnName]
{
get
{
string message = null;
if (columnName == "Cost" && this.Cost > 10000.00)
{
message = "This price is high enough to require confirmation";
}
return message;
}
}
}
The Cost property is bound in the ViewModel to a textbox, allowing the user to enter their own data. Prior to implementing IDataErrorInfo, users typing text in this box resulted in it being highlighted in red, but no error message was shown. That was deemed to be sufficient warning.
Now, typing text into the box flicks on the Style I've implemented to show errors and that's fine. Plus there's a message: Value '[text]' could not be converted, but that's a bit esotric for users. The real problem is that if someone types in a figure greater than 10000.00 and triggers the custom message and then removes that value and replaces it with text, the old error message stays in place.
With a breakpoint, it's clear what's happening: because the View is expecting this to be a double, it never even gets to checking to see if IDataErrorInfo has changed. How can I clear the error message and replace it with something more meaningful? I can't parse Cost because, of course, it's a double so it'll never even get set if someone enters text?
public class Price : IDataErrorInfo
{
private double _costDouble;
private string _cost;
public string Cost
{
get {
return _cost;
}
set {
_cost = value;
double.TryParse(value, out _costDouble);
}
}
public string Error
{
get { throw new NotImplementedException(); }
}
string IDataErrorInfo.this[string columnName]
{
get
{
string message = null;
if (columnName == "Cost")
{
double doubleVal;
if (double.TryParse(this.Cost, out doubleVal))
{
if (doubleVal > 1000.0)
message = "This price is high enough to require confirmation";
}
else {
message = "Format error";
}
}
return message;
}
}
}
You ultimately have to use a String-Property for the Binding to the Textbox.
Bonus: You can now validate if the User enters a numeric value.