我在哪里进行验证

时间:2013-10-08 10:05:00

标签: c# wpf validation mvvm

我正在“动态”学习MVVM,但我找不到验证器类的正确位置。

我有我的businesslogic和WPF项目的项目。最后一个是在MVVM模式之后创建的。

该应用程序的目的是从外部设备读取数据并验证该数据。 验证方法(每个设备属性为1)存储在BL中。

在GUI中,我需要显示设备属性以及它们是否有效。

我现在拥有的:

  • 1次观看(MainWindowView
  • 1 viewmodel(MainWindowViewModel
  • 1个型号(DeviceModel

MainWindowViewModel具有DeviceModel类型的属性。此属性用于在视图上显示设备数据。 目前,我有一些类型为bool HasValidPropXxxx 属性,这些属性绑定到相应文本框的Background - 属性(使用IValueConverter来自{{ 1}}到bool)。 因为它只有5个属性,我认为它们在一个好地方。

现在需求已经发生了变化(显然),我必须展示并验证更多的设备属性。 我正在考虑创建一个Color - 类,它包含所有 HasValidPropXxxx 属性,并对BL进行验证调用。

我想知道的是:

  1. 这是一种很好的思考方式(特别是关于MVVM)
  2. 我应该在哪个位置放置验证器:模型?的ViewModels?其他文件夹?

2 个答案:

答案 0 :(得分:1)

对于验证,我总是实现IDataErrorInfoINotifyDataErrorInfo接口,第二个更新,(在我看来)更好。在模型或数据类型类中实现这些接口时,可以在定义属性的位置提供验证。这对我来说是完全合理的,因为它还允许使用多个属性值执行复杂的验证。

以下是IDataErrorInfo的简短示例...首先实现Item索引器方法:

public override string this[string propertyName]
{
    get
    {
        string error = string.Empty;
        if (propertyName == "Name" && Name == string.Empty) error = "Enter Name";
        else if (propertyName == "Age" && Age < 18) error = "You're too young";
        return error;
    }
}

IDataErrorInfo接口公开名为Error的属性,当模型类的任何相关属性发生更改时,此索引器会设置该属性。我们可以在UI中Bind向此属性显示错误消息,但只使用此接口一次无需自定义:

<TextBlock Text="{Binding Error}" />
<TextBlock Text="{Binding Name}" />
<TextBlock Text="{Binding Age}" />

更新&gt;&gt;&gt;

当我想根据Error属性中是否有错误消息来更改某些内容时,我会在模型基类中添加bool属性:

public bool HasError
{
    return Error != null && Error != string.Empty;
}

然后我只使用此bool属性和BoolToWhateverConverter ...在您的情况下,您需要创建BooleanToBrushConverter。如果您需要帮助,请提出另一个问题,我会留意。

更新2&gt;&gt;&gt;

@Koen,您是正确的HasError属性反映了模型对象中是否存在任何验证错误。但是,没有什么可以阻止您将另一个属性添加到特定的数据类型类中:

string nameError = "Enter Name";
...
public override string this[string propertyName]
{
    get
    {
        string error = string.Empty;
        if (propertyName == "Name" && Name == string.Empty) error = nameError;
        else if (propertyName == "Age" && Age < 18) error = "You're too young";
        return error;
    }
}

public bool HasNameError
{
    return Error == nameError;
}

当然,最好在模型类中使用这些属性,这样就不必在模型类出现的每个视图模型中复制代码。

答案 1 :(得分:0)

您可以使用system.componentmodel.dataannotations来验证属性。然后调用validate方法来执行这些数据注释。 虽然看着你的声誉,我假设你知道这些。如果是这样,请忽略这个答案