I've looked at a few examples of implementing the IDataErrorInfo
interface and all of those implemented that somewhat like this:
public string Error => null;
public string this[string columnName] {
get {
string res = null;
switch (columnName) {
case "FirstName":
if (FirstName != "test") res = "First Name Invalid!";
break;
case "LastName":
if (LastName != "test") res = "Last Name Invalid!";
break;
}
return res;
}
}
What's the purpose of public string Error
and how to use that instead of returning null
? In xaml
some of those examples used a predefined style targeting TextBox
and others used a Label
or ToolTip
like these:
<TextBox x:Name="Fname"
Text="{Binding FirstName, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}"
ToolTip="{Binding ElementName=Fname, Path=(Validation.Errors)[0].ErrorContent}" />
<Label Content="{Binding ElementName=Fname, Path=(Validation.Errors).CurrentItem.ErrorContent}"/>
Can I avoid x:Name="Fname"
and ElementName=Fname
when it's used as a ToolTip
and shorten the expression (Validation.Errors)[0].ErrorContent
?
EDIT
Probably DataAnnotations
is the most elegant way to to validate individual property as well as the whole model/viewmodel along with these:
public string Error => null;
public string this[string columnName] {
get {
var validationResults = new List<ValidationResult>();
if (Validator.TryValidateProperty(
GetType().GetProperty(columnName).GetValue(this),
new ValidationContext(this) { MemberName = columnName },
validationResults
)) return null;
return validationResults.First().ErrorMessage;
}
}
To validate the whole model I just am supposed to call:
Validator.TryValidateObject(this, new ValidationContext(this), null, true);
in CanExecute
of ICommand
. This example also didn't use the public string Error
.
The Error
property is ignored by the WPF binding engine so you only have to care about to implement the indexer.
By the way, it's recommended to implement and use the INotifyDataErrorInfo
interface instead of IDataErrorInfo
since .NET Framework 4.5.