Currently I am using the IDataErrorInfo interface to implement validation in a WPF application. The indexer which is part of that interface allows to validate a single property, like so:
public string this[string columnName]
{
get
{
switch (columnName)
{
case "LastName":
if (string.IsNullOrEmpty(this.LastName))
return "LastName must not be empty.";
break;
// case, case, case, etc., etc.
}
return null;
}
}
If a validation error occurs I display an asterisk with a tooltip next to the TextBox.
What can I do if I have validation rules which are not strictly related to a single property? For instance, if a domain entity representing an order has a shipping date and an invoice date and I want to validate the rule that the invoice date must be later than or equal to the shipping date?
Of course I could force this rule into the indexer as well by checking the relationship twice, once for columnName "ShippingDate" and once for columnName "InvoiceDate" and then marking the error with an asterisk at both input fields in the UI, like so:
public string this[string columnName]
{
get
{
switch (columnName)
{
case "ShippingDate":
case "InvoiceDate":
if (this.ShippingDate > this.InvoiceDate)
return "Invoice date must not be before shipping date.";
break;
}
return null;
}
}
But I would prefer to have an "object level" or "cross property" validation independently from the indexer (the indexer should only report an invalid "single property state") and display those object level or relationship errors separately on the UI.
I was hoping that the Error property of the IDataErrorInfo interface might have this purpose of object level validation. WPF calls the indexer for property validation when I specify ValidatesOnDataErrors=True in the Binding expression of a TextBox, for instance. But I couldn't find a way to tell WPF to call the Error property whenever I change some data in my input fields. Maybe my guess about the purpose of this property is wrong?
How can I implement cross-property validation in WPF?
Thank you for suggestions in advance!
Regarding my question if I can setup a binding so that WPF tests automatically the
Errorproperty of theIDataErrorInfointerface I found the following negative answer here:Question from someone:
Answer from Microsoft Online Community Support:
So, the
Errorproperty doesn't have any more value than defining my own hand-made property (likeCrossPropertyErrors) in the domain entities. WPF doesn't support testing of theErrorproperty in an easy built-in way.Edit: The quotes above are from March 2008, so very likely related to .NET 3.5. But I couldn't find any sign that this did change in .NET 4.0.
Edit: Finally I had to create my own hand-written binding to the
Errorproperty and fill it with appropriate cross-property error messages. Every change of any other property in the class raises now aPropertyChangedEvent of both the changed property itself and of theErrorproperty to refresh the Error message on the UI.Edit 2
It looks roughly like this:
Model (or ViewModel) classes:
NotificationObjectimplementsRaisePropertyChanged:Then in a view the
Errorproperty is bound to - for instance - aTextBlockwhich displays the cross-property validation errors:So: Every changed property on the model will notify the WPF binding engine about a (potential) change of the
Errorproperty causing therefore an update of the cross-property validation text.