IDataErrorInfo索引器和数组属性

时间:2016-02-01 10:49:19

标签: c# arrays wpf

我有一个实现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;
      }
   }
}

1 个答案:

答案 0 :(得分:0)

使用绑定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数组的包装器,它将通知索引值更改,这将触发验证索引器代码。