MVVM - 验证 [英] MVVM - Validation

查看:130
本文介绍了MVVM - 验证的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们正在试图找出验证在业务逻辑或模式MVVM做验证。
我实现了由异常类型的验证我们的业务逻辑 - 简化框图可以在这里找到:
替换文本

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.


  • 值1和值2的模型必须是不一样的,所以我们已经得到了验证功能在每个那些寻找平等的价值,并抛出一个异常,如果发生这种情况

  • 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

现在,如果我们设置值1 0和值2〜1一切都好

now, if we set Value1 to 0 and Value2 to 1 everything is fine

值1被在GUI中设置1 - >这一个被标记为红色,因为其他值的验证未被触发,所以值2的GUI没有标记故障

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

值2被设定为2的GUI,现在我们已经到了一个有效的状态,但只值2得到验证,所以值1还是标记为错误的

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

有没有办法解决这个问题的一个常见的​​模式?我们不希望引入两个文本框之间的GUI的依赖,因为这种逻辑应该只存在于业务逻辑层。

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.

相反,实施验证的例外我们也可以实现IDataErrorInfo的接口,但问题依然存在,没有办法根据值再次验证他们的价值观,至少没有我可以看到给力:)

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 :)

任何帮助表示赞赏。

欢呼声中,
曼尼

cheers, manni

[清理,删除不必要的步骤]

[cleanup, removed unecessary step]

15.11.2010 - 第2部分

15.11.2010 - Part2

确定,这里的大重新思考,我们正在与businesslogic层去。这里是我们目前规划中的配置:

(图片有点小这里缩放,请打开它在一个单独的窗口中显示它的全尺寸)
一切都只是如何通知所有不同的编辑器的的ViewModels /型号克隆更多的还是不太清楚,如果在企业数据模型逻辑得到改变。做到这一点的一种方法是跟踪克隆模型中,创建它们的业务逻辑。当数据模型是使用商业逻辑的commit()改变时,所有其他已注册模式克隆可以通知的变化,并进一步传播他们。或者业务逻辑可以张贴到所有的ViewModels订阅,使他们得到的变化,以及一个事件 - 任何人都可以给我一个提示什么是更好的。

ok, big rethought here, we're going with the businesslogic tier. here is our current planned configuration: ( the image is a bit small scaled here, please open it on a separate window to show it in full size) everything is more or less clear, except how to notify all the viewmodels/model clones of the different editors if the data-model under the business logic gets changed. one way to do it is to track the cloned models in the business logic which creates them. When the data-model is changed using the business logic commit(), all the other registered model clones can be notified of the changes and propagate them further. alternatively the business logic could post an event to which all the viewmodels subscribe so that they get the changes as well - could anyone give me a hint what's better?

再次感谢帮助,对不起,我是如此的思维受阻;)

Thanks again for the help, sorry i'm so mind-blocked ;)

推荐答案

您可以考虑使用的System.ComponentModel.IDataErrorInfo 接口。这个非常方便的接口使您能够:

You could consider using the System.ComponentModel.IDataErrorInfo interface. This very handy interface gives you the ability to:


  • 在一个MVVM合规的方式做验证

  • 做自定义验证任何特定领域

  • 您的UI绑定到验证错误

您在您的视图模型实现IDataErrorInfo的(甚至在你看来示范基地实际上,在派生视图模型覆盖它)。由于数据绑定的性质,我需要检查的值都在那里在视图模型,我可以测试它们的任意组合。当然,你仍然有你的验证在你的业务层,但你不再需要去一趟到业务层(或模型)只是为了实现一些验证。

You implement IDataErrorInfo on your viewmodel (or even virtually in your view model base, and override it in your derived view models). Due to the nature of databinding, the values i need to check are all there in the view model, and i can test any combination of them. Of course you still have your validation in your business layer, but you no longer need to make a trip to your business layer (or Model) just to effect some validation.

下面是一个(WPF)屏幕收集一些用户的详细信息并执行他们基本验证一个简单的例子:

Here is a quick example from a (WPF) screen that gathers some user details and does basic validation on them:

C#代码:

    #region IDataErrorInfo Members

    /// <summary>
    /// Gets an error message indicating what is wrong with this object.
    /// </summary>
    /// <value></value>
    /// <returns>An error message indicating what is wrong with this object. The default is an empty string ("").</returns>
    public override string Error
    {
        get
        {
            return this["UserCode"] + this["UserName"] + this["Password"] + this["ConfirmedPassword"] + this["EmailAddress"];
        }
    }

    /// <summary>
    /// Gets the <see cref="System.String"/> with the specified column name.
    /// </summary>
    /// <value></value>
    public override string this[string columnName]
    {
        get
        {
            switch (columnName)
            {
                case "UserCode":
                    if (!string.IsNullOrEmpty(UserCode) && UserCode.Length > 20)
                        return "User Code must be less than or equal to 20 characters";
                    break;

                case "UserName":
                    if (!string.IsNullOrEmpty(UserCode) && UserCode.Length > 60)
                        return "User Name must be less than or equal to 60 characters";
                    break;

                case "Password":
                    if (!string.IsNullOrEmpty(Password) && Password.Length > 60)
                        return "Password must be less than or equal to 60 characters";
                    break;

                case "ConfirmedPassword":
                    if (Password != ConfirmedPassword)
                        return Properties.Resources.ErrorMessage_Password_ConfirmedPasswordDoesntMatch; 
                    break;

                case "EmailAddress":
                    if (!string.IsNullOrEmpty(EmailAddress))
                    {
                        var r = new Regex(_emailRegex);
                        if (!r.IsMatch(EmailAddress))
                            return Properties.Resources.ErrorMessage_Email_InvalidEmailFormat;
                    }
                    break;
            }
            return string.Empty;
        }
    }

    #endregion

和这里是XAML标记两个文本框的页面(注意特别是 ValidatesOnDataErrors ValidatesOnExceptions 的属性文本绑定):

and here is the XAML markup for two of the textboxes on the page (note particularly the ValidatesOnDataErrors and ValidatesOnExceptions properties in the Text binding):

<TextBox Name="UserCodeTextBox" 
         Text="{Binding UserCode, 
                Mode=TwoWay, 
                UpdateSourceTrigger=PropertyChanged, 
                ValidatesOnDataErrors=True, 
                ValidatesOnExceptions=True, 
                NotifyOnSourceUpdated=True, 
                NotifyOnTargetUpdated=True}" 
         GotFocus="Input_GotFocus"
         VerticalAlignment="Top"
         Margin="165,0,150,0"  
         CharacterCasing="Upper"
         />

<TextBox Name="UserNameTextBox" 
         Text="{Binding UserName, 
                Mode=TwoWay, 
                UpdateSourceTrigger=PropertyChanged, 
                ValidatesOnDataErrors=True, 
                ValidatesOnExceptions=True, 
                NotifyOnSourceUpdated=True, 
                NotifyOnTargetUpdated=True}" 
         GotFocus="Input_GotFocus"
         VerticalAlignment="Top"
         Margin="165,30,0,0"  
         />

这篇关于MVVM - 验证的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆