Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

IDataErrorInfo calling bound object rather than DataContext

Tags:

c#

mvvm

wpf

I have a model:

public class Product
{
    public int Rating { get; set; }
    ...
}

and a View Model:

public class ProductViewModel: IDataErrorProvider
{
    public int Temperature { get; set; }
    public Product CurrentProduct { get; set; }

    public string this[string columnName]
    {
        get
        {
            if (columnName == "Rating")
            {
                if (CurrentProduct.Rating > Temperature)
                    return "Rating is too high for current temperature";
            }
            return null;
        }
    }
}

My view has an instance of ProductViewModel as the DataContext. The view has the field:

<TextBox Text={Binding Path=CurrentProduct.Rating, ValidatesOnDataErrors=True} .../>

By default, validation occurs on the IDataErrorProvider of the bound object (Product), not the DataContext (ProductViewModel). So in the above instance, ProductViewModel validation is never called. This is just a simple example but illustrates the problem. The model doesn't (and shouldn't) know about Temperature, so the design dictates that the VM should perform the validation on that field.

Yes, I could hack it and replicate the bound properties of the model directly in the ViewModel, but I would have thought there must be an easier way to redirect the call to the VM rather than the model?

like image 456
trayracer Avatar asked Oct 23 '22 07:10

trayracer


1 Answers

If you want your viewmodel to validate a property named "Rating" by IDataErrorInfo, then your viewmodel must actually have a property called Rating and you must bind to it, which would mean to replicate the bound properties of the model in the viewmodel.

Anyway this blog article could be interesting for you (Validating Business Rules in MVVM). The author adds a Validation delegate to the model that the viewmodel can set. This allows you to validate your model using data that it does not known, like the Temperature in your example.

like image 115
Klaus78 Avatar answered Nov 01 '22 16:11

Klaus78