English 中文(简体)
C# 自定义事件处理程序
原标题:
  • 时间:2008-10-20 12:52:34
  •  标签:

如果我有一项财产:

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

我如何生成和处理自定义事件,在列表中添加一个名称时调用“onNamesChanged”?

最佳回答

你应该查看 System.ComponentModel.BindingList,特别是 ListChanged 事件

问题回答

BindingList很可能是您最好的选择,因为它具有内置的更改跟踪和各种现有事件可供使用。以下是将自定义事件公开添加到转发到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);
        }
    }

BindingList的一种选择是ObservableCollection-在这种情况下,您需要订阅自己的事件处理程序到CollectionChanged事件,然后根据操作触发您的事件。

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>)-这需要很多工作,但效益却很小。

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

你创建一个外部类,其中包含用于在访问属性时进行前置和/或后置处理的代码,检查属性值在前置和后置之间是否更改,并触发一个事件。

记住,在进行比较时(在处理程序代码中),可能会陷入无限循环(你调用属性访问器,该访问器调用AOP处理程序,该处理程序调用访问器,依此类推),因此你可能需要反射到包含此属性的类中来获得后备字段。





相关问题
热门标签