We're trying to figure out validation in the mvvm doing validation in the business logic or model. I've implemented the validate by exception type in our business logic - a simplified diagram can be found here:
If we've got lot's of inputs that are independent of each other, there is no problem, the exception is thrown, the textbox catches it an marks it's borders red for each wrong input. However, when we've got dependent values we're in trouble. e.g.
* Value1 and Value2 in the model must not be the same, so we've got a validate function in each of those looking for the equals value and throw an exception if that happens
* now, if we set Value1 to 0 and Value2 to 1 everything is fine
* Value1 gets set in the GUI to 1 --> this one gets marked red, because the validation of the other values is not triggered, so Value2 in the GUI is not marked faulty
* Value2 gets set to 2 in the GUI, now we've reached a valid state, but only Value2 gets validated, so Value1 still is marked as faulty
Is there a common pattern to solve that issue? we don't want to introduce a dependency in the GUI between the two textboxes, because this logic should only be present in the business logic layer.
Instead of implementing the validate by exception one could also implement the IDataErrorInfo interface, but the problem still exists, there is no way to force depending values to validate their values again, at least none that i can see :)
We did some development and testing using the IDataErrorInfo interface for validation purposes, but there are still some issues left with this approach. we had some discussions wether to split business logic and our model classes, currently we use the model property getters to directly work with them in the viewmodel, but the properties can only be set by using the business logic. For validation the business logic is used too, so the whole logic should be stored in this layer, not in the viewmodel. We would still have two string mappings left to deal with.
* The classic from View to ViewModel - PropertyName to Property. This mapping also includes mapping the ViewModel Property to the Model PropertyName (this could be setup using the expression workaround to get rid of the strings and a map to do that automatically)
* in the Business Logic: the PropertyName of the Model to set has to be mapped to the validation rules and the setter. I'm not quite sure how to solve that in an elegant way.
Additionally if Value1 and Value2 depend on each other (e.g. are not allowed to have the same value) - in the current model to re-evaluate the properties in the view, a propertychanged event would have to be called for both values if one of them was set. but this seems a reasonable price to pay, since the business logic can trigger the propertychanged events as well, and it knows about all the dependencies
Cheers and thanks for any input or help
manni