I think the root of your problem is that your view model isn't really a model of the view.
Every property in the view model should be of a type appropriate for the view, not the data model. If you have a numeric property in the data model and you're using a text box in the view to edit it, the property in the view model should be a string.
The view model properties contain the values appearing in the view irrespective of whether or not those values are valid. The only time there should be a discrepancy between the value in the view and the value in the view model is when an editable control has the focus, the user is changing its value, and binding hasn't pushed the new value back to the view model yet.
If you do it this way, I think most of the concerns you've expressed here go away. After you populate a view model object (assuming that you've implemented validation in its setters, and you're not bypassing its setters to update the properties' backing fields directly), its properties are valid or not irrespective of whether or not its view has been instantiated yet.
In my view model classes, I implement a Dictionary<string, string>
property named Errors
. The validation in the property setters populates Errors
with each property's validation error, or null if the property is valid. This makes implementing IDataErrorInfo.Item
simple:
public string this[string propertyName]
{
get
{
return Errors.ContainsKey(propertyName) ? Errors[propertyName] : null;
}
}
I can also implement this property:
public bool IsValid { get { return !(Errors.Values(x => x != null).Any()); } }
which can be used anywhere I need to check to make sure that the view model's current state is valid - say, in the CanExecute
property of a Command
.