繁体   English   中英

在C#中,如何修改数组中的元素时触发PropertyChanged事件

[英]In C#, how to trigger the PropertyChanged event when an elements in a array gets modified

我有一个array属性,只要该数组的任何元素发生更改,我都想在其中通知。

private double[] _OffsetAngles = new double[3];
public double[] OffsetAngles
    {
        get { return _OffsetAngles; }
        set
        {
            _OffsetAngles = value;
            NotifyPropertyChanged();
        }
    }

如果OffsetAngles的任何元素被更改,我想获取通知。 即如果我设置OffsetAngles [1] = 20; //应该触发。 如果我设置OffsetAngles [0] = 40; //触发应该再次发生。

想象一下,您不是在使用double,而是在使用某些类。 然后该类的字段已更改。 是否应该更改数组的属性? 当然不是。 因此,您可以考虑多种解决方案:

  • 使用ObservableCollection及其SetItem方法
  • 使用ObservableCollection ,而不是分配值,然后删除并插入值
  • 而不是重复使用一些实现INotifyPropertyChanged类,并且当文件更改引发此事件时,如果目的是数据绑定,则应该是正确的方法
  • 每次都重新创建Array (麻烦且效率低下,但仍然可以使用)

因此,正如其他人所提到的,在您的情况下,当数组本身(而不是数组的任何元素)发生更改时,将触发NotifyPropertyChanged()。

如果希望元素能够触发事件,则必须实现一个类,如下所示:

public class NotifyingData<T> : INotifyPropertyChanged 
{
    public event PropertyChangedEventHandler PropertyChanged;

    private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    private T _Data;
    public T Data
    {
        get { return _Data; }
        set { _Data = value; NotifyPropertyChanged(); }
    }
}

然后用该类填充数组:

_OffsetAngles[0] = new NotifyingData<double> { Data = 10 };

我目前无法使用VS,因此可能会有一些错误,但这对您来说应该是正确的概念。

本示例说明如何创建并绑定到从ObservableCollection类派生的集合,该类是一个收集类,当添加或删除项目时会提供通知。

public class NameList : ObservableCollection<PersonName>  
{  
    public NameList() : base()  
    {  
        Add(new PersonName("Willa", "Cather"));  
        Add(new PersonName("Isak", "Dinesen"));  
        Add(new PersonName("Victor", "Hugo"));  
        Add(new PersonName("Jules", "Verne"));  
    }  
  }  

  public class PersonName  
  {  
      private string firstName;  
      private string lastName;  

      public PersonName(string first, string last)  
      {  
          this.firstName = first;  
          this.lastName = last;  
      }  

      public string FirstName  
      {  
          get { return firstName; }  
          set { firstName = value; }  
      }  

      public string LastName  
      {  
          get { return lastName; }  
          set { lastName = value; }  
      }  
  } 

集合中的对象必须满足“绑定源概述”中描述的要求。 特别是,如果您使用的是OneWay或TwoWay(例如,当源属性动态更改时,您希望UI更新),则必须实现适当的属性更改通知机制,例如INotifyPropertyChanged接口。

参考: https : //docs.microsoft.com/zh-cn/dotnet/framework/wpf/data/how-to-create-and-bind-to-an-observablecollection

前段时间我遇到了同样的问题。 每当数据更改时,我都必须更新DataTable,这就是我在程序中解决它的方式:

public ObservableCollection<KeyStroke> keyList = new ObservableCollection<KeyStroke>();
public class KeyStroke : INotifyPropertyChanged
{
    // KeyStroke class storing data about each key and how many types it received
    private int id;
    private int numPress;
    public KeyStroke(int id, int numPress)
    {
        Id = id;
        NumPress = numPress;
    }
    public int Id
    {
        get => id;
        set
        {
            id = value;
            NotifyPropertyChanged("Id");
        }
    }
    public int NumPress
    {
        get { return this.numPress; }
        set
        {
            this.numPress = value;
            NotifyPropertyChanged("NumPress");
        }
    }

    public event PropertyChangedEventHandler PropertyChanged; //This handle the propertyChanged
    private void NotifyPropertyChanged(String propertyName)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); //This is the WPF code for the DataGrid but you can replace it by whatever you need
    }
}

这应该对您有帮助。 您也可以将条件放入属性的getter / setter中,但我认为这并不是很漂亮

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM