views:

18

answers:

2

(I know there's some close duplicates out there, but none of them were able to help me, please hear me out)

I have the setters of my model throwing appropriate exceptions when something attempts to set an invalid value. This works wonders for validation when the user types a new value.

However, when I create a new model object, the initial state may be invalid (no value in description, etc..) This of course won't validate but without something trying to set the value, no exception will be thrown for the ExceptionValidationRule to catch.

The simple solutions I have are:

  1. Catch the change in the current object, trigger a Current.Value = Current.Value type evaluation to cause the .set_Value portion to run and re-validate (thus triggering the ExceptionValidationRule to update the state. However, this feels dirty and wrong

  2. Catch the change in the object and call a manual property-by-property validation and somehow update the HasError and Validation.Errors which would trigger the object to update it's visual state. This feels more like a hack than anything, and I'm not sure how to go about it

Now the biggest problem is, I could probably wire something up that'd work for either of these situations. But they'd completely violate my MVVM structure, I have no clue how to work this kind of validation right into MVVM.

  • I've looked at creating my own binding type, no dice.
  • I've looked at creating a decorator to capture my children, might work: need more info
  • I've looked at IDataError implementations, this won't work for me as it requires the use of the this[string] indexer, which would conflict with my existing model object's implementations.

So I'm out of ideas, and I'm turning to you SO, for some insight on how to tackle this problem.

+1  A: 

If your model can be in an invalid state, then having it implement IDataErrorInfo seems like the most appropriate solution. Is the issue with IDataErrorInfo that you already have an indexer on your model that takes in a string parameter? You could use explicit interface implementation to implement IDataErrorInfo separately from your public indexer:

public class Model
    : IDataErrorInfo
{
    public string this[string parameter]
    {
        get { /* Your current indexer */ }
    }

    string IDataErrorInfo.this[string columnName]
    {
        get { /* IDataErrorInfo indexer implementation */ }
    }

    /* ... */
}

If you can't modify your model at all, then you may want to make a ViewModel class that wraps the model and implements IDataErrorInfo.

Quartermeister
A: 

I agree with Quartermeister that the IDataErrorInfo interface might be the best option. When you can't implement the this[string] indexer then you can still implement the interface with explicit members.

string IDataErrorInfo.this[string memberName] 
{ 
    get { return ... } 
}

You might have a look at the BookLibrary sample application of the WPF Application Framework (WAF) which shows how the IDataErrorInfo interface can be used together with MVVM.

jbe