WPF基于异常的验证,未触发初始状态

时间:2010-06-24 20:33:17

标签: c# .net wpf validation mvvm

(我知道那里有一些密切的重复,但没有一个能够帮助我,请听我说)

当某些东西试图设置无效值时,我的模型的setter会抛出适当的异常。当用户键入新值时,这会产生验证效果。

然而,当我创建一个新的模型对象时,初始状态可能是无效的(描述中没有值等等。)这当然不会验证但是没有试图设置值的东西,不会抛出任何异常让ExceptionValidationRule抓住。

我所拥有的简单解决方案是:

  1. 捕获当前对象的更改,触发Current.Value = Current.Value类型评估以使.set_Value部分运行并重新验证(从而触发ExceptionValidationRule更新状态。然而,这感觉很脏又错误

  2. 捕获对象中的更改并调用手动逐个属性验证和 以某种方式更新HasErrorValidation.Errors,这会触发对象更新它的视觉状态。 这感觉更像是黑客而不是任何东西,而且我不确定该怎么做

  3. 现在最大的问题是,我可能会提出一些可以解决这些问题的问题。但是他们完全违反了我的MVVM结构,我不知道如何在MVVM中进行这种验证。

    • 我看过创建自己的绑定类型,没有骰子。
    • 我看过创建一个装饰来捕捉我的孩子,可能会工作:需要更多信息
    • 我查看了IDataError实现,这对我不起作用,因为它需要使用this[string]索引器,这会与我现有的模型对象的实现冲突。

    所以我没有想法,我转向 SO,以便了解如何解决这个问题。

2 个答案:

答案 0 :(得分:2)

如果您的模型可能处于无效状态,那么让它实现IDataErrorInfo似乎是最合适的解决方案。问题IDataErrorInfo是否已经在模型上有一个索引器,它接受一个字符串参数?您可以使用explicit interface implementation与公共索引器分开实施IDataErrorInfo

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

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

    /* ... */
}

如果根本无法修改模型,那么您可能需要创建一个包装模型并实现IDataErrorInfo的ViewModel类。

答案 1 :(得分:1)

我同意Quartermeister的说法, IDataErrorInfo 界面可能是最佳选择。当您无法实现 this [string] 索引器时,您仍然可以使用显式成员实现该接口。

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

您可以查看 WPF Application Framework (WAF) BookLibrary 示例应用程序,其中显示了IDataErrorInfo接口如何与MVVM一起使用。