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
Error
property of theIDataErrorInfo
interface I found the following negative answer here:Question from someone:
Answer from Microsoft Online Community Support:
So, the
Error
property doesn't have any more value than defining my own hand-made property (likeCrossPropertyErrors
) in the domain entities. WPF doesn't support testing of theError
property 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
Error
property and fill it with appropriate cross-property error messages. Every change of any other property in the class raises now aPropertyChanged
Event of both the changed property itself and of theError
property to refresh the Error message on the UI.Edit 2
It looks roughly like this:
Model (or ViewModel) classes:
NotificationObject
implementsRaisePropertyChanged
:Then in a view the
Error
property is bound to - for instance - aTextBlock
which 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
Error
property causing therefore an update of the cross-property validation text.