在C#中,当数组中的元素被修改时,如何触发PropertyChanged事件
我有一个数组属性,在该属性中,每当该数组的任何元素发生更改时,我都要发出通知在C#中,当数组中的元素被修改时,如何触发PropertyChanged事件,c#,arrays,wpf,inotifypropertychanged,C#,Arrays,Wpf,Inotifypropertychanged,我有一个数组属性,在该属性中,每当该数组的任何元素发生更改时,我都要发出通知 private double[] _OffsetAngles = new double[3]; public double[] OffsetAngles { get { return _OffsetAngles; } set { _OffsetAngles = value; NotifyPropertyChanged
private double[] _OffsetAngles = new double[3];
public double[] OffsetAngles
{
get { return _OffsetAngles; }
set
{
_OffsetAngles = value;
NotifyPropertyChanged();
}
}
如果偏移角的任何元素发生更改,我希望得到通知。
i、 e.如果我设置偏移角[1]=20//触发应该发生。
如果我设置偏移角[0]=40//触发器应该再次发生。此示例演示如何创建并绑定到从ObservableCollection类派生的集合,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; }
}
}
公共类名称列表:ObservableCollection
{
公共名称列表():base()
{
添加(新人名(“威拉”、“凯瑟”);
添加(新人名(“伊萨克”、“迪内森”);
添加(新人名(“维克多”、“雨果”);
添加(新人名(“朱尔斯”、“凡尔纳”);
}
}
公共类人名
{
私有字符串名;
私有字符串lastName;
PublicPersonName(先字符串,后字符串)
{
this.firstName=first;
this.lastName=last;
}
公共字符串名
{
获取{return firstName;}
设置{firstName=value;}
}
公共字符串姓氏
{
获取{return lastName;}
设置{lastName=value;}
}
}
集合中的对象必须满足绑定源概述中描述的要求。特别是,如果使用单向或双向(例如,希望在源属性动态更改时更新UI),则必须实现适当的属性更改通知机制,如INotifyPropertyChanged接口
参考:假设您使用的不是double,而是某个类。然后那个类的文件已经改变了。数组raise属性是否应该更改?当然不是。因此,您可以考虑多种解决方案:
- 使用
及其observedcollection
方法SetItem
- 使用
删除并插入值,而不是赋值ObservableCollection
- 不要重复使用实现
的某个类,当dobule更改引发此事件时,如果其目的是数据绑定,那么它应该是正确的方法INotifyPropertyChanged
- 每次重新创建
(繁琐且效率低下,但仍能正常工作)阵列
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
}
}
public observetecollection keyList=new observetecollection();
公共类击键:INotifyPropertyChanged
{
//击键类,用于存储每个键的数据及其接收的类型
私有int-id;
私人国际公寓;
公共击键(int-id,int-numPress)
{
Id=Id;
NumPress=NumPress;
}
公共整数Id
{
get=>id;
设置
{
id=值;
NotifyPropertyChanged(“Id”);
}
}
公共国际新闻
{
获取{返回this.numPress;}
设置
{
this.numPress=值;
通知财产变更(“NumPress”);
}
}
public event PropertyChangedEventHandler PropertyChanged;//此句柄处理PropertyChanged
私有void NotifyPropertyChanged(字符串propertyName)
{
PropertyChanged?.Invoke(这是新的PropertyChangedEventArgs(propertyName));//这是DataGrid的WPF代码,但您可以根据需要替换它
}
}
这应该对你有帮助。您也可以在属性的getter/setter中设置条件,但我认为这并不太好,正如其他人所提到的,在您的例子中,当数组本身发生更改时,而不是数组的任何元素发生更改时,您将触发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(); }
}
}
公共类NotifyingData:INotifyPropertyChanged
{
公共事件属性更改事件处理程序属性更改;
私有void NotifyPropertyChanged([CallerMemberName]字符串propertyName=”“)
{
if(PropertyChanged!=null)
{
PropertyChanged(这是新的PropertyChangedEventArgs(propertyName));
}
}
私人T_数据;
公共T数据
{
获取{return_Data;}
设置{u Data=value;NotifyPropertyChanged();}
}
}
然后用该类填充数组:
_OffsetAngles[0] = new NotifyingData<double> { Data = 10 };
_OffsetAngles[0]=newnotifyingdata{Data=10};
我现在无法访问VS,因此可能会出现一些错误,但这应该是适合您的概念。您是否尝试过使用ObservableCollection?还是必须使用数组?是的,我也尝试过ObservableCollection。但对于tat来说,如果元素发生变化,事件就不会被触发。我试图给你一个答案,而你却投了反对票。我不知道为什么?如果使用
ObservableCollection
,将通知绑定的集合类型属性,如ItemsControl的ItemsSource属性。但是,您将不会收到OffsetAngles属性本身的更改通知,因为在向其添加或删除元素时它不会更改。集合实例没有更改。但是,您可以将CollectionChanged事件处理程序附加到ObservaleCollection,该事件处理程序只调用NotifyPropertyChanged(nameof(OffsetAngles))
本文没有回答这个问题。它忽略了一个要点,即OP在添加、删除或设置元素时要求更改其偏移角属性的通知。ObservableCollection不会神奇地做到这一点。如果这不是答案,请告知您的答案?请参阅我的注释中的解释作为说明,如果您引入一个类似PersonName类的item类,这