IDataErrorInfo与所有文本框具有相同的验证

时间:2014-01-30 08:49:12

标签: c# wpf xaml mvvm

目前我正在使用 IDataErrorInfo ,但问题是我想使用 对于所有textBox,这个确切的代码验证,现在如果我输入textBox1框的无效数据,所有textBox2 都会出现红色边框。

我不想使用特定情况用于所有文本框(我有更多15 ...),因为验证中的所有内容对于所有文本框都应该相同。我该如何划分?

   public string Error
        {
            get { throw new NotImplementedException(); }
        }

        public string this[string columnName]
        {
            get
            {
                var error = "";
                switch (columnName)
                {
                    case "ListItem":

                        if (ListItem != null)
                        {
                            var list = new List<String> { "FirstName", "LastName", "BusinessItem", "BusinessItems" };

                            string value = ListItem.Trim();

                            var isValid = true;
                            if (!string.IsNullOrEmpty(value))
                            {
                                isValid = list.Contains(value);
                                if (!isValid)
                                {
                                    error = "Please enter either FirstName, LastName, BusinessItem, or BusinessItems";
                                }
                            }
                        }
                        break;
                }
                return error;
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;
    }

Xaml

<TextBox  name="textBox1" Text="{Binding Path=ListItem,UpdateSourceTrigger=PropertyChanged,ValidatesOnDataErrors=True}"
              HorizontalAlignment="Center" VerticalAlignment="Center" Width="200"/>


<TextBox  name="textBox2" Text="{Binding Path=ListItem,UpdateSourceTrigger=PropertyChanged,ValidatesOnDataErrors=True}"
              HorizontalAlignment="Center" VerticalAlignment="Center" Width="200"/>

1 个答案:

答案 0 :(得分:0)

我假设您将每个TextBox绑定到不同的属性。您可以使用反射来使用其名称访问该属性。将其分解为函数,您可以执行与此类似的操作:

private bool validateProperty(string propertyName)
{            
    string value = GetType().GetProperty(propertyName).GetValue(this, null) as string;
    if (value != null)
    {
        var list = new List<String> { "FirstName", "LastName", "BusinessItem", "BusinessItems" };

        value = value.Trim();

        if (!string.IsNullOrEmpty(value))
            return list.Contains(value);
    }

    return false;    
}

public string this[string columnName]
{
    get
    {
        // if you validate more properties, you may want to check if columnName
        // follows a pattern (eg. columnName.Contains("ListItem") )

       if (!validateProperty(columName))
          return "Please enter either FirstName, LastName, BusinessItem, or BusinessItems";

       return string.Empty;
     }
}

修改

从您的评论中我发现我的假设是错误的,您可能会对IDataErrorInfo验证的工作方式感到困惑,所以让我从您的约束中解释一下:

Text="{Binding Path=ListItem, 
               UpdateSourceTrigger=PropertyChanged,
               ValidatesOnDataErrors=True}"

通过指定ValidatesOnDataErrors=True,您实际上正在为绑定添加DataErrorValidationRule。当TextBox.Text属性更改时调用此规则,并为绑定源(DataContext.ListItem)的绑定属性调用IDataErrorInfo.Item(索引器)。

因此,每次TextBox中的文本发生更改时,规则都会调用DataContext["ListItem"],如果返回的内容与空字符串不同,则验证失败,更新attached Validation properties - WPF默认通过显示控件周围的红色矩形来处理。

因此,只要您使用ValidatesOnDataErrors=true ,您就会遇到通过IDataErrorInfo执行验证的问题,DataContext仅支持ListItem个对象中每个属性的单个错误。因此,

  1. 您无法知道哪个控件触发了绑定属性(ListItem)的验证。
  2. 您只能为绑定属性({{1}})返回一个错误,并且该属性同时只有一个验证错误处于活动状态。
  3. 如果您使用的是.NET 4.5或Silverlight 4+,则可以使用支持每个属性的多个错误INotifyErrorDataError Interface