7

如果我有财产:

public list<String> names { get; set; }

每当将名称添加到列表中时,如何为名为“onNamesChanged”的参数生成和处理自定义事件?

4

5 回答 5

12

BindingList 可能是您的最佳选择,因为它具有内置的更改跟踪和您可以使用的各种现有事件。下面是一个为 Add 公开自定义事件的示例,该事件转发到 BindingList 事件。


    class Example
    {
        private BindingList<string> m_names = new BindingList<string>();
        public IEnumerable<string> Names { get { return m_names; } }
        public event AddingNewEventHandler NamesAdded
        {
            add { m_names.AddingNew += value; }
            remove { m_names.AddingNew -= value; }
        }
        public void Add(string name)
        {
            m_names.Add(name);
        }
    }
于 2008-10-20T13:06:42.807 回答
10

您应该检查System.ComponentModel.BindingList,特别是ListChanged 事件

于 2008-10-20T12:57:41.077 回答
10

BindingList 的一种替代方法是ObservableCollection - 在这种情况下,您希望将自己的事件处理程序订阅到CollectionChanged事件并根据操作触发您的事件。

于 2008-10-20T13:08:47.043 回答
0

David Mohundro 展示了一种方法;另一种选择是从 Collection<T> 继承并覆盖各种方法:

class Foo {}
class FooCollection : Collection<Foo>
{
    protected override void InsertItem(int index, Foo item)
    {
        // your code...
        base.InsertItem(index, item);
    }
    protected override void SetItem(int index, Foo item)
    {
        // your code...
        base.SetItem(index, item);
    }
    // etc
}

最后,您可以根据第一原则创建自己的列表 (IList, IList<T>) - 工作量大,收益少。

于 2008-10-20T13:06:33.040 回答
0

一种非正统的方法可能是使用诸如 PostSharp 之类的 AOP 框架在调用访问器之前/之后“编织”一个处理程序,这会触发一个事件。

您创建一个外部类,其中包含访问属性时的 pre 和/或 post 处理代码,检查属性的值是否在 pre 和 post 之间发生变化,并引发事件。

请记住,在获取值进行比较时(在您的处理程序代码中),您可能会进入一个无限循环(您调用属性访问器,它调用 AOP 处理程序,它调用访问器等等),所以您可能需要反映到包含此属性的类中以获取支持字段。

于 2008-10-20T13:33:28.603 回答