0

我有一个可以发布事件的 objectRaiser,例如事件“PropertyChanged”。我还有另一个 objectListener,它监听来自第一个 objectRaiser 的引发事件。

如何从 objectRaiser 实例中删除 objectListener 监听的事件处理程序?

我需要重复一些重要的事情:remove 的事件处理程序来自 objectListener。不适合我从 objectRaiser 中删除所有出版物。我在另一个问题中看到了这一点,但似乎不是我的问题的解决方案。

非常感谢您的帮助。

4

2 回答 2

0

I'm not sure if this is exactly what you're after ... but in the code below, we can use Reflection to remove handlers from the instance of the ObjectRaiser contained in the ObjectListener:

namespace ObjectEvents
{
    class Program
    {
        private class ObjectRaiser
        {
            public event EventHandler PropertyChange;

            private string name;
            public string Name
            {
                get
                {
                    return name;
                }
                set
                {
                    name = value;
                    PropertyChange(this, new EventArgs());
                }
            }
        }

        private class ObjectListener
        {
            private ObjectRaiser or;

            public ObjectListener(ObjectRaiser or)
            {
                this.or = or;
                or.PropertyChange += new EventHandler(PropertyChange);
            }

            public void PropertyChange(object sender, EventArgs e)
            {
                Console.WriteLine("I'm listening!");
            }

            public void RemoveHandlers()
            {
                var lfi = or.GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Instance);

                foreach(var fi in lfi)
                {
                    var eh = fi.GetValue(or) as EventHandler;
                    if (eh != null)
                    {
                        foreach (var del in eh.GetInvocationList())
                        {
                            foreach (var ev in or.GetType().GetEvents())
                            {
                                ev.GetRemoveMethod().Invoke(or, new object[] { del });
                            }
                        }
                    }
                }
            }
        }

        static void Main(string[] args)
        {
            var or = new ObjectRaiser();
            var ol = new ObjectListener(or);

            //This will raise the event
            or.Name = "New Name";
            ol.RemoveHandlers();
            //This will throw an exception because the event has no handler associated
            or.Name = "Weird Name";

            Console.ReadLine();
        }
    }
}

Note: this is a very simple example and would certainly require significant modifications for real-world use.

于 2012-02-16T18:01:09.990 回答
0

从内部objectRaiser

MyEvent = null;

从外部:您不能,因为您无权访问存储处理程序的委托。但是,您可以在 中添加一个公共ClearHandlers()方法objectRaiser,并从您想要的任何地方调用它。

于 2012-02-16T17:06:59.337 回答