MVVM - 谁负责

时间:2016-04-27 08:13:37

标签: c# wpf validation mvvm

我此刻有点困惑,因为我不确定像#34;谁负责验证模型数据"。

举个例子:

我有一个应用程序,其中Person和特定设备之间的关系可视化。

public class Person{
    public string Firstname {get; set;}
    public string Lastname {get; set;}
    public SomeSortOfDevice SomeSortOfDevice {get; set;}
}

public class SomeSortOfDevice{
    public DateTime DeviceExpiration {get; set;}
    public string DeviceSerialCode {get; set;}
    //public bool IsSerialCodeValid{get{
    //     SomeValidationLogic()
    //}
}

在View中,App-User可以更改Device的数据。 现在有一些规则 - 例如,DeviceExpiration绑定到TextBox,但只有在设置了有效的SerialCode时才应该启用。

但是谁决定SerialCode是否有效?模特本身? ViewModel?模型是否应该持有额外的财产" IsSerialValid"或者如何将TextBox的IsEnabled属性绑定到该规则?

修改1

public class ViewModel{
    public Person SelectedPerson {get; set;}
}

这就是我如何使用上面的模型 - View将在SeletedPerson上获得一些绑定。

修改2

我认为它比我之前解释的要复杂得多。让我们假设设备是一个令牌,我想确定用户是否输入了某些内容 - 如果他输入了内容,是否有效?

如果验证应该在模型中处理(因为我现在已经得到它),模型将如下所示:

public Token{
    public DateTime ExpirationDate {get; set;}
    public string Serial {get; set;}
    public bool IsTokenExpired{
        get{
            return ExpirationDate.Date < DateTime.Now;
        }
    }
    public bool IsTokenValid{
        get{
            return new Regex("[0-9]{8,12}").Match().Success;
        }
    }
    public bool IsTokenSet{
        get{
            return TokenSerial.Length > 0;
        }
    }
}

现在启用TextBox,其中User应该输入(或选择)一个Date,Binding看起来像这样:

<TextBox IsEnabled="{Binding SelectedPerson.Token.IsTokenValid}"/>

这很好用,但我对模型中的验证规则并不是很了解。

3 个答案:

答案 0 :(得分:2)

嗯,这只是一个意见,但我会这样做。

首先,您的模型应该有一个验证方法,例如public bool ValidateSerial(string serial);

然后,在您的ViewModel中,您将拥有绑定到TextBox的属性,并且您将在那里进行检查,例如:

_private string _serialNumber;
public string SerialNumber
{
    get
    {
         return this._serialNumber;
    }
    set
    {
         this._serialNumber=value;
         RaisePropertyChanged("SerialNumber");
         this.IsSerialValid=Model.ValidateSerial(string serial);
         RaisePropertyChanged("IsSerialValid");
    }
    public bool IsSerialValid { get; set;}
}

IsSerialValid属性是您绑定到另一个TextBox的IsEnabled属性的属性。

希望这对你有意义。

答案 1 :(得分:1)

我认为这一切都取决于具体的设计。通常,您可以在模型中实现一些逻辑检查,但模型不应该(也不能)与UI通信。因此,如果出现问题,模型通常会拒绝存储数据。

控件的可见性应在ViewModel中处理,正如您在代码中正确建议的那样。但是,在您输入错误的序列代码的情况下,不会更改IsValid属性(因为in是按需计算的)。更好的方法是检查DeviceSerialCode的setter中的Serial Code,并从那里设置IsSerialCodeValid。为了使UI能够反映变化,您的ViewModel还应该实现INotifyPropertyChanged接口,并向其setter中的属性发出更改信号。

答案 2 :(得分:0)

无需持有额外财产。只需实现INotifyPropertyChanged接口,该接口在属性值更改时发出事件。

您可以在视图模型中收听属性的属性更改事件,并在那里进行检查。这就是视图在MVVM模型中的更新方式。

您还可以将文本框的IsEnabled属性绑定到viewmodel属性,该属性在检查期间设置是否包含有效值。

如果需要,还可以使用转换器作为IsEnabled属性并将文本作为命令参数传递,以便转换器检查文本并根据需要设置文本框的IsEnabled属性的bool值。