0

I have a objectRaiser which can publish events, for example the event "PropertyChanged". I have too another objectListener, which listen the raised events from first objectRaiser.

How I can remove the event handlers listeneds by objectListener from objectRaiser instance?

I need repeat something important: the event handlers for remove is from objectListener. Don't works for me remove all publications from objectRaiser. I look that in another questions but don't seems a solution for my problem.

Regards and many thanks for the help.

skaffman
  • 398,947
  • 96
  • 818
  • 769

2 Answers2

0

From inside objectRaiser:

MyEvent = null;

From outside: you can't, because you don't have access to the delegate that stores the handlers. You could however add a public ClearHandlers() method in objectRaiser, and call it from wherever you want.

Thomas Levesque
  • 286,951
  • 70
  • 623
  • 758
  • Based on the question, I think the desire is to remove all of the delegates for a specific subscriber, not all of then. – cadrell0 Feb 16 '12 at 18:22
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.

LiquidPony
  • 2,188
  • 1
  • 17
  • 19
  • That code seems delete all active handlers of his event "PropertyChange" from all listeners, but we want delete all handlers ONLY from a concrete objectListener instance. – nullPointer Feb 17 '12 at 09:13