Delete all event handlers in one go

Problem. I have a document class that contains a list of objects. These objects trigger events such as SolutionExpired, DisplayExpiredetc. The document should answer that.

Documents can sometimes exchange objects, but one object should never be a "part" of more than one document.

My document class contains a bunch of methods that serve as event handlers. Whenever an object enters a document, I use AddHandlerto set up events, and whenever an object is deleted from a document, I use RemoveHandlerto undo the damage. However, there are times when it’s hard to make sure that all the steps are completed properly, and I could thus get rogue event handlers.

In short; How to remove all handlers pointing to a specific method? Please note: I do not have a list of potential event sources, they can be saved anywhere.

Sort of:

RemoveHandler *.SolutionExpired, AddressOf DefObj_SolutionExpired
+5
source share
3 answers

You can use Delegate.RemoveAll(). (The part that interests you is in button2_Click)

public void Form_Load(object sender, EventArgs e) 
{ 
    button1.Click += new EventHandler(button1_Click);
    button1.Click += new EventHandler(button1_Click);
    button2.Click += new EventHandler(button2_Click);
    TestEvent += new EventHandler(Form_TestEvent);
}
event EventHandler TestEvent;
void OnTestEvent(EventArgs e)
{
    if (TestEvent != null)
        TestEvent(this, e);
}
void Form_TestEvent(object sender, EventArgs e)
{
    MessageBox.Show("TestEvent fired");
}
void button2_Click(object sender, EventArgs e)
{
    Delegate d = TestEvent as Delegate;
    TestEvent = Delegate.RemoveAll(d, d) as EventHandler;
}
void button1_Click(object sender, EventArgs e)
{
    OnTestEvent(EventArgs.Empty);
}

You should notice that it does not change the contents of the delegates that you pass it to it, it returns the changed delegate. Therefore, you will not be able to change events on the button that you dropped on the form from the form, because it button1.Clickcan only use +=or -=, and not =. This will not compile:

button1.Click = Delegate.RemoveAll(d, d) as EventHandler;

, , , , . - , , !

+5
public class TheAnswer
{
    public event EventHandler MyEvent = delegate { };

    public void RemoveFromMyEvent(string methodName)
    {
        foreach (var handler in MyEvent.GetInvocationList())
        {
            if (handler.Method.Name == methodName)
            {
                MyEvent -= (EventHandler)handler;
            }
        }
    }
}

2: . , , .

, , . , ; , , , . , .

, : , / .

: ( ), , .

, , , , , , !

+1

Use Delegate.RemoveAll(possibly using reflection if the Delegate instance is private).

+1
source

All Articles