使用INotifyDataErrorInfo验证依赖项属性

时间:2015-10-22 17:52:39

标签: c# wpf validation mvvm data-binding

我在网格中有一个带有Textbox的用户控件,如下所示:

<TextBox Text="{Binding Username}"></TextBox>

usercontrol的代码隐藏实现了INotifyDataErrorInfoINotifyPropertyChanged。这就是我的代码隐藏的样子(除了上面提到的接口实现)

public TestControl()
{
    InitializeComponent();
    this.DataContext = this;
}

private string _username;
public string Username
{
    get { return _username; }
    set
    {
        _username = value;
        if (_username.Length < 3)
            SetErrors("Username", new List<string> { "Usernames should be at least 3 characters long" });
        OnPropertyChanged("Username");
    }
}

SetErrors只是一个向IEnumerable添加错误的函数,INotifyDataErrorInfo.GetErrors将返回该错误。这非常有效。当我写少于3个字符的文本时,文本框变为红色。这正是我所期待的。

现在我希望MainWindow的viewmodel设置此文本框。为此,Username字段应该是依赖属性,因此我可以绑定它。但问题是我现在无法验证它。我创建了一个依赖属性,并尝试在ValidateValueCallback验证它,但INotifyDataErrorInfo成员不是静态的。所以我无法联系到他们。我该怎么办?

1 个答案:

答案 0 :(得分:0)

将用户名放在MainViewModel中,并在UserControl内部使用RelativeSource绑定绑定到它,如

"{Binding RelativeSource={RelativeSource AncestorType=Window}, Path=DataContext.Username}"

您可以使用CallerMemberName属性替换显式名称指示。

编辑
定义依赖项属性时,可以确定每当值发生更改时将引发的事件。作为参数,它引用了类,在其中定义了它,就您的项目而言,它将是您的UserControl。然后,您可以在此对象上调用任何方法,根本不需要是静态的。以下代码描述了概念,而不是精确的解决方案,根据您的要求进行调整:

   public static readonly DependencyProperty PropertyTypeProperty = DependencyProperty.Register(
        "PropertyType", typeof (propertyType), typeof (PasswordBoxDP), new PropertyMetadata((x, y) =>
        {
            var userControlClass = x as UserControlClass;
            userControlClass.Validate();
        }));

    private void Validate()
    {

    }

顺便说一下,你的案子中的绑定将无法正常工作。您定义了引用自身的DataContext,因此当您在依赖项属性上设置绑定时,它将启动在UserControl中的搜索。