这与问题非常相似,但具体针对列表。
How to trigger event when a variable's value is changed?
每次我的列表已修改时,我想运行一个方法。
我假设使用属性并在'set'中放置一个方法将是解决此问题的正确方法。我开始用这样的东西
public class Stuff
{
private List<Things> _myThings;
public List<Things> MyThings
{
get
{
return _myThings;
}
private set
{
_myThings= value;
runWhenListIsChanged();
}
}
}
但是,当我使用'RemoveAt'或'RemoveRange'这样的命令时
public class StuffChanger
{
Stuff.MyThings.RemoveAt(5);
}
直接进入'get'属性并更改列表。
我错误地认为它会使用set(因为它改变了列表)但事实并非如此。调试时(使用Visual Studio中的“step into”工具)我注意到可以使用'get'访问器修改List。
在这种特殊情况下,我不希望每次读取列表时都调用一个方法,因为这会导致性能增加或导致堆栈溢出。所以这不是一个选择。
如果有人有任何提示或代码建议,我将非常感激!非常感谢。
答案 0 :(得分:2)
正如您所观察到的,您编写的用于操作列表的代码确实没有在属性中设置新列表。
相反,这段代码:
Stuff.MyThings.RemoveAt(5);
可以被认为与此类似:
var list = Stuff.MyThings;
list.RemoveAt(5);
因此,它从getter中读取列表,然后直接操作列表本身。
要在列表本身发生变化时收到通知,您需要使用List<T>
以外的其他内容,因为此类型没有任何支持该要求的功能。
一个好的候选人将是ObservableCollection<T>
,你可以将事件处理程序连接到CollectionChanged事件。
请注意,这只会观察列表的更改,而不会查看列表中的元素。如果您在列表中添加或删除项目,您将收到通知,但如果您执行以下代码:
MyStuff.MyThings[0].SomeProperty = SomeNewValue;
然后你不会从列表中获得任何通知。您将不得不在元素类型上实现类似INotifyPropertyChanged的内容,并将事件处理程序与其挂钩以获取这些通知。