我的应用程序使用MVVM模式。我的TextBox
绑定到我的ViewModel属性(类型字符串)。
当TextBox
的内容通过用户输入更改时,我想执行一些验证。
所以,目前,我的代码是
<TextBox Text="{Binding XmlContentAsString, UpdateSourceTrigger=PropertyChanged}" />
我的ViewModel有这个属性和字段:
private string _xmlContentAsString;
public string XmlContentAsString
{
get { return _xmlContentAsString; }
set
{
if (_xmlContentAsString == value)
return;
_xmlContentAsString = value;
PerformValidiationLogic(value);//This is where I am unsure
}
}
现在,这可行但是,我不知道为什么,我不喜欢这个!在该属性中包含该方法的一些感觉“被黑客入侵”。
在使用MVVM模式时,有人可以告诉我这是否是正确的方法?
答案 0 :(得分:1)
有不同类型的验证。 对于简化的验证字符串长度或允许的字符等,您可以使用DataAnnotations并将验证放在属性的属性中。你需要包括 使用System.ComponentModel.DataAnnotations;
然后例如将字符串保持为9个字符:
[StringLength(9)]
public string StringValue
{
get
{
return stringValue;
}
set
{
this.stringValue = value;
}
}
然后验证有点复杂,并且有效地强制执行您的业务逻辑。 关于如何做到这一点似乎有很多观点。理想情况下它应该属于模型,以便可以重用验证,但显然可以通过viewmodel调用。
我个人会偶尔在属性设置器中调用方法调用,对我而言,这就是有能力创建setter和getter的全部原因 - 否则除了自动属性之外没有其他任何东西。
但如果它很复杂或异步,那么你可以遇到问题。 我会非常小心地使用UpdateSourceTrigger = PropertyChanged,因为这意味着你将为每个角色解雇它。
答案 1 :(得分:1)
在您的示例中,您对值执行验证逻辑,但如果验证失败,那将是什么结果?通常,您希望通知用户验证失败。如果是这种情况,那么我建议使用IDataErrorInfo(例子可以在这里找到:
http://codeblitz.wordpress.com/2009/05/08/wpf-validation-made-easy-with-idataerrorinfo/)。
如果您计划在不通知用户的情况下覆盖该值,则可以接受在设置器中进行验证(但出于个人原因仍然不是粉丝)。
答案 2 :(得分:0)
在我看来,这是正确的方法。我会为你的ViewModel编写一个基类,它包含一个设置属性的方法,调用PropertyChanged并验证是否有一些验证规则附加到该属性。
例如:
public abstract class ValidableViewModel
{
private List<ValidationRule> _validationRules;
public ValidableViewModel()
{
_validationRules = new List<ValidationRule>();
}
protected virtual void SetValue<T, T2>(Expression<Func<T>> expression,
ref T2 backend, T2 value)
{
if (EqualityComparer<T2>.Default.Equals(backend, value))
return;
backend = value;
OnPropertyChanged(expression);
Validate(expression.Name, value);
}
protected void Validate(string propertyName, object value)
{
foreach(var validationRule in _validationRules)
{
if(validationRule.PropertyName == propertyName)
validationRule.Execute(value);
}
}
}
代码不完整,遗漏了很多。但它可能是一个开始; - )
答案 3 :(得分:0)
我个人并不建议在你的财产中加入如此多的逻辑。我会使用绑定到事件的命令,即文本框的lostfocus事件,并在那里执行验证。
我会用这样的东西:
<TextBox Text="{Binding XmlContentAsString, UpdateSourceTrigger=PropertyChanged}">
<interactivity:Interaction.Triggers>
<interactivity:EventTrigger EventName="LostFocus">
<interactivity:InvokeCommandAction Command="{Binding LostFocusCommand, Mode=OneWay}"/>
</interactivity:EventTrigger>
</interactivity:Interaction.Triggers>
</TextBox>
然后在您的视图模型中使用LostFocusCommand命令,并使用验证逻辑 我使用mvvm-light,可以为此提供更详细的示例。 (您需要在xaml顶部包含混合交互声明)