IDataErrorInfo 索引器和数组属性

本文关键字:数组 属性 索引 IDataErrorInfo | 更新日期: 2023-09-27 18:32:52

我有一个自定义类,它实现了 IDataErrorInfo 接口,并且有几个属性绑定到 UI 中的文本框。string this[string name]索引器适用于常规的 int/string 属性,但我似乎无法让它与 string[] 属性一起使用。例如绑定

<TextBox Text="{Binding StringEntry, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}" Width="30" />

有效,但绑定

<TextBox Text="{Binding StringList[0], UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}" Width="30" />

不会。int[] 属性也是如此。它甚至根本不触发索引器函数调用。有没有办法让它与数组属性一起使用,还是会强制我为每个数组元素定义一个属性?

编辑:完整的类,因为看起来我不清楚。

class MyObject : INotifyPropertyChanged, IDataErrorInfo
{
   public MyObject()
   {
      stringEntry = "text";
      stringList = new string[] { "text1", "text2" };
   }
   private string[] stringList;
   public string[] StringList
   {
      get
      {
         return this.stringList;
      }
      set
      {
         if (this.stringList != value)
         {
            this.stringList = value;
            this.NotifyPropertyChanged("StringList");
         }
      }
   }
   private string stringEntry
   public string StringEntry
   {
      get
      {
         return this.stringEntry;
      }
      set
      {
         if (this.stringEntry != value)
         {
            this.stringEntry = value;
            this.NotifyPropertyChanged("StringEntry");
         }
      }
   }
   public override string Error
   {
      get
      {
         return null;
      }
   }
   public event PropertyChangedEventHandler PropertyChanged;
   public void NotifyPropertyChanged(string propName)
   {
      if (this.PropertyChanged != null)
      {
         this.PropertyChanged(this, new PropertyChangedEventArgs(propName));
      }
   }
   public override string this[string name]
   {
      get
      {
         string result = null; // I have a breakpoint here, it's never triggered
                               // when I change the text in the StringList
                               // It DOES work for the StringEntry though.
         switch (name)
         {
            case "StringEntry":
               if (string.IsNullOrEmpty(StringEntry))
               {
                  result = "Entry cannot be emtpy";
               }
               break;
            case "StringList[0]": // doesn't work like this
               if (string.IsNullOrEmpty(StringList[0]))
               {
                  result = "Entry cannot be emtpy";
               }
               break;
            case "StringList": // nor like this
               if (string.IsNullOrEmpty(StringList[0]))
               {
                  result = "Entry cannot be emtpy";
               }
               break;
         }
         return result;
      }
   }
}

IDataErrorInfo 索引器和数组属性

使用绑定Text="{Binding StringList[0],,它将始终引用 StringList 属性的第一个索引字符串,并且不会调用索引器。

如果要引用索引器,请尝试使用Text="{Binding [StringList[0]],在这种情况下StringList[0]它将被视为索引器的键,而不是属性本身。

编辑: 更新

    class MyObject : INotifyPropertyChanged, IDataErrorInfo
{
    public MyObject()
    {
        stringEntry = "text";
        stringList = new string[] { "text1", "text2" };
    }
    private string[] stringList;
    public string[] StringList
    {
        get
        {
            return this.stringList;
        }
        set
        {
            if (this.stringList != value)
            {
                this.stringList = value;
                this.NotifyPropertyChanged("StringList");
            }
        }
    }
    private string stringEntry;
    public string StringEntry
    {
        get
        {
            return this.stringEntry;
        }
        set
        {
            if (this.stringEntry != value)
            {
                this.stringEntry = value;
                this.NotifyPropertyChanged("StringEntry");
            }
        }
    }
    public string Error
    {
        get
        {
            return null;
        }
    }
    public event PropertyChangedEventHandler PropertyChanged;
    public void NotifyPropertyChanged(string propName)
    {
        if (this.PropertyChanged != null)
        {
            this.PropertyChanged(this, new PropertyChangedEventArgs(propName));
        }
    }
    public string this[string name]
    {
        get
        {
            string result = null; // I have a breakpoint here, it's never triggered
                                  // when I change the text in the StringList
                                  // It DOES work for the StringEntry though.
            switch (name)
            {
                case "StringEntry":
                    if (string.IsNullOrEmpty(StringEntry))
                    {
                        result = "Entry cannot be emtpy";
                    }
                    break;
                case "[(0)]": // works like this, this block is updated
                    if (string.IsNullOrEmpty(StringList[0]))
                    {
                        result = "Entry cannot be emtpy";
                    }
                    if (string.IsNullOrEmpty(StringList[1]))
                    {
                        result = "Entry cannot be emtpy";
                    }
                    break;
                case "StringList": // not required
                    if (string.IsNullOrEmpty(StringList[0]))
                    {
                        result = "Entry cannot be emtpy";
                    }
                    break;
            }
            return result;
        }
    }
    public string this[int index]
    {
        get { return StringList[index]; }
        set
        {
            StringList[index] = value;
        }
    }
}

        <TextBox Grid.Column="1" Text="{Binding Path=[(sys:Int32)0], UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}" VerticalAlignment="Center" HorizontalAlignment="Stretch" Margin="5"/>

在这里,我们为数组StringList实现了包装器,它将在索引值更改时发出通知,这将触发验证索引器代码。