我试图在我的mvvm项目中构建验证,但发现了一些问题......
首先我尝试使用CodeContract,所以我在域层中的实体上有一个简单的合约:
public class Class1
{
public virtual int ID {get;set;}
private string _desc;
public virtual string Desc
{
get { return _desc; }
set {
Contract.Requires(String.IsNullOrEmpty(value) == false);
Contract.Requires(value.Length >2, "> 2 required ");
_desc = value;
}
}
public Class1(int id)
{this.Id = id;}
}
然后在我的Caliburn.micro Boostrapper的Configure方法中添加
ConventionManager.ApplyValidation = (binding, viewModelType, property) =>
{ binding.ValidatesOnExceptions = true; };
在视图中我简单地说
<TextBox x:Name="Class1Description" ></TextBox>
让ViewModel公开名为Class1Description的字符串属性(我不公开原始的Class1对象)
运行应用程序的问题是抛出异常并将焦点从窗体切换到我的属性的set方法上的visualstudio,按F5将焦点返回到窗体并且desc字段为红色。
如何避免焦点切换?
在互联网上搜索验证我发现IDataErrorInfo似乎是最好的方式,所以我尝试DataAnnotation并将[MinLength(2)]添加到我的属性并更改bootstrapper
ConventionManager.ApplyValidation = (binding, viewModelType, property) =>
{binding.ValidatesOnDataErrors = true; };
视图中的新文本框是
<TextBox x:Name="Class1Description" Text="{Binding Path=Class1Description,
ValidatesOnDataErrors=True, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
</TextBox>
现在我运行应用程序,在Desc文本框中写一个字符串,将焦点切换到其他文本框,没有任何反应......
我错过了什么?
答案 0 :(得分:0)
ok 2件事,1你的Caliburn会引起一点怪异,不要命名控件,然后使用与Property相同名称的绑定。其次在类示例中,您将Desc而不是Class1Description作为属性。属性名称必须与路径匹配。
对于属于.net(非第三方)的文本框,框架(CM)中的UpdateSourceTrigger默认为PropertyChange。
<TextBox Text="{Binding Desc, ValidatOnErrors =True, Mode=TwoWay}" />
public virtual string Desc
{
get { return _desc; }
set {
Contract.Requires(String.IsNullOrEmpty(value) == false);
Contract.Requires(value.Length >2, "> 2 required ");
_desc = value;
NotifyOfPropertyChange(()=>Desc); //Added
}
}
如果没有为IDataNotifyErrorInfo设置类,那么您将看不到任何错误。其次,如果没有设置模板,那么它也不会显示任何东西。