【问题标题】:How to validate entities in Caliburn.Micro如何在 Caliburn.Micro 中验证实体
【发布时间】:2014-07-16 12:15:30
【问题描述】:

我正在尝试在我的 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)] 添加到我的属性并更改引导程序

ConventionManager.ApplyValidation = (binding, viewModelType, property) =>
{binding.ValidatesOnDataErrors = true; };

视图中的新文本框是

<TextBox x:Name="Class1Description" Text="{Binding Path=Class1Description, 
     ValidatesOnDataErrors=True, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
</TextBox>

现在我运行应用程序,在 Desc 文本框中编写一个单字符字符串,将焦点切换到其他文本框,什么也没有发生...

我错过了什么?

【问题讨论】:

  • 在您的课程中,当您不发出通知时,视图模型如何知道属性是否发生了变化?其次,要验证什么属性?我认为深度绑定不需要使用 Class1Desc 吗?
  • 是 caliburn.micro 告诉 viewmodel 视图中属性的变化(基于文本框名称)。要验证的属性是我的唯一一个视图模型(如我所写): Class1Description 。不明白你最后一个问题

标签: c# validation mvvm data-annotations caliburn.micro


【解决方案1】:

好的 2 件事,1 你导致 Caliburn 有点吓坏了,不要命名控件,然后使用具有相同名称的属性绑定。其次,在类示例中,您将 Desc 而不是 Class1Description 作为属性。属性名称必须与路径匹配。

对于属于 .net(不是第 3 方)的文本框,框架 (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 设置类,那么您将不会看到任何错误。其次,如果没有设置模板,那么它也不会显示任何内容。

【讨论】:

  • 好的,我使用主 x:name 进行绑定,但添加 validateOnErrors 需要绑定,所以我只是留下了所有内容。所以我将删除 x:name。我没有在我的 ViewModel 中公开模型:所以视图没有绑定到 MyClass 的 Desc 属性,而是绑定到 MyClassViewModel 的 Class1Description
  • 那么路径就是 Class1Description.Desc,否则它不知道 Class1Description 是什么以及它被绑定的属性..
  • 我重写了我在原始帖子中写的内容:让 ViewModel 公开一个名为 Class1Description 的字符串属性(我不公开原始 Class1 对象)。 Class1Description 是一个字符串属性,然后我使用自动映射器将 ViewModel 映射到实体。基本上 Class1Description 是一个字符串变量,用于存储接下来将保存到实体对象的 Desc 属性中的值
猜你喜欢
  • 2013-05-16
  • 2012-07-31
  • 2021-05-17
  • 1970-01-01
  • 1970-01-01
  • 2012-06-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多