441 Stimmen

So entfernen Sie alle Ereignisbehandler aus einem Ereignis

Um einen neuen Ereignishandler für ein Steuerelement zu erstellen, können Sie wie folgt vorgehen

c.Click += new EventHandler(mainFormButton_Click);

oder dies

c.Click += mainFormButton_Click;

und um einen Event-Handler zu entfernen, können Sie Folgendes tun

c.Click -= mainFormButton_Click;

Aber wie entfernt man alle Ereignisbehandler aus einem Ereignis?

196voto

xsl Punkte 16574

Ich habe eine Lösung auf der Website MSDN-Foren . Der folgende Beispielcode entfernt alle Click Ereignisse aus button1 .

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();

        button1.Click += button1_Click;
        button1.Click += button1_Click2;
        button2.Click += button2_Click;
    }

    private void button1_Click(object sender, EventArgs e)  => MessageBox.Show("Hello");
    private void button1_Click2(object sender, EventArgs e) => MessageBox.Show("World");
    private void button2_Click(object sender, EventArgs e)  => RemoveClickEvent(button1);

    private void RemoveClickEvent(Button b)
    {
        FieldInfo f1 = typeof(Control).GetField("EventClick", 
            BindingFlags.Static | BindingFlags.NonPublic);

        object obj = f1.GetValue(b);
        PropertyInfo pi = b.GetType().GetProperty("Events",  
            BindingFlags.NonPublic | BindingFlags.Instance);

        EventHandlerList list = (EventHandlerList)pi.GetValue(b, null);
        list.RemoveHandler(obj, list[obj]);
    }
}

192voto

Stephen Punak Punkte 1975

Ihr macht es euch VIEL zu schwer. Es ist so einfach:

void OnFormClosing(object sender, FormClosingEventArgs e)
{
    foreach(Delegate d in FindClicked.GetInvocationList())
    {
        FindClicked -= (FindClickedHandler)d;
    }
}

93voto

Jorge Ferreira Punkte 92489

Von Alle Ereignisbehandler entfernen :

Unmittelbar nein, zum großen Teil, weil Sie das Ereignis nicht einfach auf Null setzen kann.

Indirekt könnte man den eigentlichen Ereignis privat machen und eine Eigenschaft erstellen, die alle Ereignisse Delegierten verfolgt, die hinzugefügt/subtrahiert es.

Nehmen Sie das Folgende:

List<EventHandler> delegates = new List<EventHandler>();

private event EventHandler MyRealEvent;

public event EventHandler MyEvent
{
    add
    {
        MyRealEvent += value;
        delegates.Add(value);
    }

    remove
    {
        MyRealEvent -= value;
        delegates.Remove(value);
    }
}

public void RemoveAllEvents()
{
    foreach(EventHandler eh in delegates)
    {
        MyRealEvent -= eh;
    }
    delegates.Clear();
}

73voto

LionSoft Punkte 1419

Die akzeptierte Antwort ist nicht vollständig. Es funktioniert nicht für Ereignisse, die als {add; remove;} deklariert sind.

Hier ist ein funktionierender Code:

public static void ClearEventInvocations(this object obj, string eventName)
{
    var fi = obj.GetType().GetEventField(eventName);
    if (fi == null) return;
    fi.SetValue(obj, null);
}

private static FieldInfo GetEventField(this Type type, string eventName)
{
    FieldInfo field = null;
    while (type != null)
    {
        /* Find events defined as field */
        field = type.GetField(eventName, BindingFlags.Static | BindingFlags.Instance | BindingFlags.NonPublic);
        if (field != null && (field.FieldType == typeof(MulticastDelegate) || field.FieldType.IsSubclassOf(typeof(MulticastDelegate))))
            break;

        /* Find events defined as property { add; remove; } */
        field = type.GetField("EVENT_" + eventName.ToUpper(), BindingFlags.Static | BindingFlags.Instance | BindingFlags.NonPublic);
        if (field != null)
            break;
        type = type.BaseType;
    }
    return field;
}

51voto

Es kann nicht schaden, einen nicht existierenden Event-Handler zu löschen. Wenn Sie also wissen, welche Handler es geben könnte, können Sie sie einfach alle löschen. Ich hatte gerade einen ähnlichen Fall. Dies kann in einigen Fällen helfen.

Wie:

// Add handlers...
if (something)
{
    c.Click += DoesSomething;
}
else
{
    c.Click += DoesSomethingElse;
}

// Remove handlers...
c.Click -= DoesSomething;
c.Click -= DoesSomethingElse;

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X