2016-01-06 33 views
0

这与列表中的问题非常相似。每次修改列表(未访问)时运行一个方法

How to trigger event when a variable's value is changed?

每当我的列表是修改我想运行的方法。

我假设使用一个属性,并将一个方法放在'设置'将是正确的方法来解决这个问题。我开始用这样的

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); 
} 

,它直接进入了“得到”属性和列表变化。

我错误地推测它会使用set(因为它改变了列表),但事实并非如此。在调试时(使用Visual Studio中的'step into'工具),我注意到List可以通过使用'get'访问器进行修改。

在这种特殊情况下,我不希望每次读取某个列表时都会调用一个方法,因为这会导致性能下降或导致堆栈溢出。所以这不是一个选项。

如果有人有任何提示或代码建议,我将不胜感激!非常感谢。

+0

您可以改用'ObservableCollection'来注册'CollectionChangedEvent'。它会触发对该集合的任何操作。 –

回答

2

正如您所观察到的,您编写的用于处理列表的代码事实上并未在属性中设置新列表。

相反,此代码:

Stuff.MyThings.RemoveAt(5); 

可以被认为是类似于此:

var list = Stuff.MyThings; 
list.RemoveAt(5); 

因此,它读取列表出来的吸气剂,然后直接操纵列表本身。

要在列表本身发生更改时收到通知,您需要使用除List<T>之外的其他东西,因为此类型没有任何功能来支持该要求。

一个好的候选人将是ObservableCollection<T>,你会挂钩事件处理程序到CollectionChanged事件。

请注意,这只会观察对列表的更改,而不会观察列表中的元素。如果您添加或删除列表中的项目,你会得到通知,但如果你喜欢这个执行代码:

MyStuff.MyThings[0].SomeProperty = SomeNewValue; 

那么您将无法获得从该列表本身的任何通知。您将不得不在元素类型上实现类似INotifyPropertyChanged的东西,并将事件处理程序挂钩以获取这些通知。

+0

谢谢Lasse。我应该补充说我使用Unity 5.3,它没有.net 4.5+(我相信),所以我可能需要添加我自己的Observable Collection脚本。 – Jim

+0

尝试'BindingList'。 –

相关问题