简体   繁体   中英

Shared validation logic over two different models

Update: I've been fiddling around with a solution and I'm not quite sure if we can even do it this way. I will update the question as soon as I have a better understanding of what I want :-)


Our current project uses WPF along with the MVVM approach. Our application will have several editors, each with its own model.

The view will look like this:

总览

Each editor has its own model/viewmodel/model. The parent view's (which holds all sub editors) model contains the data from which all sub editors can be feeded.

Since the user should be able to save its current state at any time, we need to be able to validate the existing data as well (because the user might have entered invalid data). So we need the validation in two places:

  • when the user enters data
  • when the data is loaded again after starting the application

Since we do not want to convert the data into each sub editor model just to get the validation result, the parent model should be able to be validated as well.

The only way I found to achieve this, is to introduce interfaces which basically describes the structure of the data within the class which is to be validated. It might look like this:

interface IValidateModel
{
  string foo;
}

class Editor1Model : IValidateModel
{
  string foo;
  int someOtherProperty;
}

class Editor2Model: IValidateModel
{
  string foo;
  byte fooBar;      
}

class ParentModel
{
  Sub subProp;
  // some other parent model properties
}

Once disadvantage is that now the way the data is structured is defined by the interface.

Does anyone have some experience with that problem or does even have a better solution for this?

If you want to validate the user's input, then you should use ValidationRules on the bindings.

You define them by inheriting from ValidationRule and overwriting Validate() :

public class TestRule : ValidationRule
{
    public override ValidationResult Validate(object value, CultureInfo cultureInfo)
    {
        string test = value as string;

        if (text == null)
        {
            return new ValidationResult(false, "only strings are allowed");
        }
        else
        {
            return new ValidationResult(true, null);
        }
    }
}

In XAML you specify the namespace of the validation rules:

<Window xmlns:vr="clr-namespace:MyApp.ValidationRules"></Window>

And then you can use it on bindings like this:

<TextBox>
    <TextBox.Text>
        <Binding Path="MyPath">
            <Binding.ValidationRules>
                <vr:TestRule />
            </Binding.ValidationRules>
        </Binding>
    </TextBox.Text>
</TextBox>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM