我此刻有点困惑,因为我不确定像#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}"/>
这很好用,但我对模型中的验证规则并不是很了解。
答案 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值。