How to remove all event handlers from an event

后端 未结 18 1575
再見小時候
再見小時候 2020-11-22 01:20

To create a new event handler on a control you can do this

c.Click += new EventHandler(mainFormButton_Click);

or this

c.Cli         


        
相关标签:
18条回答
  • 2020-11-22 01:43

    I'm actually using this method and it works perfectly. I was 'inspired' by the code written by Aeonhack here.

    Public Event MyEvent()
    Protected Overrides Sub Dispose(ByVal disposing As Boolean)
        If MyEventEvent IsNot Nothing Then
            For Each d In MyEventEvent.GetInvocationList ' If this throws an exception, try using .ToArray
                RemoveHandler MyEvent, d
            Next
        End If
    End Sub
    

    The field MyEventEvent is hidden, but it does exist.

    Debugging, you can see how d.target is the object actually handling the event, and d.method its method. You only have to remove it.

    It works great. No more objects not being GC'ed because of the event handlers.

    0 讨论(0)
  • 2020-11-22 01:44

    I hated any complete solutions shown here, I did a mix and tested now, worked for any event handler:

    public class MyMain()
        public void MyMethod() {
            AnotherClass.TheEventHandler += DoSomeThing;
        }
    
        private void DoSomething(object sender, EventArgs e) {
            Debug.WriteLine("I did something");
            AnotherClass.ClearAllDelegatesOfTheEventHandler();
        }
    
    }
    
    public static class AnotherClass {
    
        public static event EventHandler TheEventHandler;
    
        public static void ClearAllDelegatesOfTheEventHandler() {
    
            foreach (Delegate d in TheEventHandler.GetInvocationList())
            {
                TheEventHandler -= (EventHandler)d;
            }
        }
    }
    

    Easy! Thanks for Stephen Punak.

    I used it because I use a generic local method to remove the delegates and the local method was called after different cases, when different delegates are setted.

    0 讨论(0)
  • 2020-11-22 01:46

    removes all handlers for button: save.RemoveEvents();

    public static class EventExtension
    {
        public static void RemoveEvents<T>(this T target) where T : Control
        {
           var propInfo = typeof(T).GetProperty("Events", BindingFlags.NonPublic | BindingFlags.Instance);
            var list = (EventHandlerList)propInfo.GetValue(target, null);
            list.Dispose();
        }
    }
    
    0 讨论(0)
  • 2020-11-22 01:46

    This is not an answer to the OP, but I thought I'd post this here in case it can help others.

      /// <summary>
      /// Method to remove a (single) SocketAsyncEventArgs.Completed event handler. This is 
      /// partially based on information found here: http://stackoverflow.com/a/91853/253938
      /// 
      /// But note that this may not be a good idea, being very .Net implementation-dependent. Note 
      /// in particular use of "m_Completed" instead of "Completed".
      /// </summary>
      private static void RemoveCompletedEventHandler(SocketAsyncEventArgs eventArgs)
      {
         FieldInfo fieldInfo = typeof(SocketAsyncEventArgs).GetField("m_Completed", 
                                                    BindingFlags.Instance | BindingFlags.NonPublic);
         eventArgs.Completed -= (EventHandler<SocketAsyncEventArgs>)fieldInfo.GetValue(eventArgs);
      }
    
    0 讨论(0)
  • 2020-11-22 01:48

    It doesn't do any harm to delete a non-existing event handler. So if you know what handlers there might be, you can simply delete all of them. I just had similar case. This may help in some cases.

    Like:

    // Add handlers...
    if (something)
    {
        c.Click += DoesSomething;
    }
    else
    {
        c.Click += DoesSomethingElse;
    }
    
    // Remove handlers...
    c.Click -= DoesSomething;
    c.Click -= DoesSomethingElse;
    
    0 讨论(0)
  • 2020-11-22 01:52

    You guys are making this WAY too hard on yourselves. It's this easy:

    void OnFormClosing(object sender, FormClosingEventArgs e)
    {
        foreach(Delegate d in FindClicked.GetInvocationList())
        {
            FindClicked -= (FindClickedHandler)d;
        }
    }
    
    0 讨论(0)
提交回复
热议问题