How to remove all event handlers from an event

后端 未结 18 1574
再見小時候
再見小時候 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:53

    Stephen has right. It is very easy:

    public event EventHandler<Cles_graph_doivent_etre_redessines> les_graph_doivent_etre_redessines;
    public void remove_event()
    {
        if (this.les_graph_doivent_etre_redessines != null)
        {
            foreach (EventHandler<Cles_graph_doivent_etre_redessines> F_les_graph_doivent_etre_redessines in this.les_graph_doivent_etre_redessines.GetInvocationList())
            {
                this.les_graph_doivent_etre_redessines -= F_les_graph_doivent_etre_redessines;
            }
        }
    }
    
    0 讨论(0)
  • 2020-11-22 01:55

    Sometimes we have to work with ThirdParty controls and we need to build these awkward solutions. Based in @Anoop Muraleedharan answer I created this solution with inference type and ToolStripItem support

        public static void RemoveItemEvents<T>(this T target, string eventName) 
            where T : ToolStripItem
        {            
            RemoveObjectEvents<T>(target, eventName);
        }
    
        public static void RemoveControlEvents<T>(this T target, string eventName)
            where T : Control
        {
            RemoveObjectEvents<T>(target, eventName);
        }
    
        private static void RemoveObjectEvents<T>(T target, string Event) where T : class
        {
            var typeOfT = typeof(T);
            var fieldInfo = typeOfT.BaseType.GetField(
                Event, BindingFlags.Static | BindingFlags.NonPublic);
            var provertyValue = fieldInfo.GetValue(target);
            var propertyInfo = typeOfT.GetProperty(
                "Events", BindingFlags.NonPublic | BindingFlags.Instance);
            var eventHandlerList = (EventHandlerList)propertyInfo.GetValue(target, null);
            eventHandlerList.RemoveHandler(provertyValue, eventHandlerList[provertyValue]);
        }
    

    And you can use it like this

        var toolStripButton = new ToolStripButton();
        toolStripButton.RemoveItemEvents("EventClick");
    
        var button = new Button();
        button.RemoveControlEvents("EventClick");
    
    0 讨论(0)
  • 2020-11-22 01:56

    Well, here there's another solution to remove an asociated event (if you already have a method for handling the events for the control):

    EventDescriptor ed = TypeDescriptor.GetEvents(this.button1).Find("MouseDown",true);            
    Delegate delegate = Delegate.CreateDelegate(typeof(EventHandler), this, "button1_MouseDownClicked");
    if(ed!=null) 
        ed.RemoveEventHandler(this.button1, delegate);
    
    0 讨论(0)
  • 2020-11-22 01:58

    I just found How to suspend events when setting a property of a WinForms control. It will remove all events from a control:

    namespace CMessWin05
    {
        public class EventSuppressor
        {
            Control _source;
            EventHandlerList _sourceEventHandlerList;
            FieldInfo _headFI;
            Dictionary<object, Delegate[]> _handlers;
            PropertyInfo _sourceEventsInfo;
            Type _eventHandlerListType;
            Type _sourceType;
    
    
            public EventSuppressor(Control control)
            {
                if (control == null)
                    throw new ArgumentNullException("control", "An instance of a control must be provided.");
    
                _source = control;
                _sourceType = _source.GetType();
                _sourceEventsInfo = _sourceType.GetProperty("Events", BindingFlags.Instance | BindingFlags.NonPublic);
                _sourceEventHandlerList = (EventHandlerList)_sourceEventsInfo.GetValue(_source, null);
                _eventHandlerListType = _sourceEventHandlerList.GetType();
                _headFI = _eventHandlerListType.GetField("head", BindingFlags.Instance | BindingFlags.NonPublic);
            }
    
            private void BuildList()
            {
                _handlers = new Dictionary<object, Delegate[]>();
                object head = _headFI.GetValue(_sourceEventHandlerList);
                if (head != null)
                {
                    Type listEntryType = head.GetType();
                    FieldInfo delegateFI = listEntryType.GetField("handler", BindingFlags.Instance | BindingFlags.NonPublic);
                    FieldInfo keyFI = listEntryType.GetField("key", BindingFlags.Instance | BindingFlags.NonPublic);
                    FieldInfo nextFI = listEntryType.GetField("next", BindingFlags.Instance | BindingFlags.NonPublic);
                    BuildListWalk(head, delegateFI, keyFI, nextFI);
                }
            }
    
            private void BuildListWalk(object entry, FieldInfo delegateFI, FieldInfo keyFI, FieldInfo nextFI)
            {
                if (entry != null)
                {
                    Delegate dele = (Delegate)delegateFI.GetValue(entry);
                    object key = keyFI.GetValue(entry);
                    object next = nextFI.GetValue(entry);
    
                    Delegate[] listeners = dele.GetInvocationList();
                    if(listeners != null && listeners.Length > 0)
                        _handlers.Add(key, listeners);
    
                    if (next != null)
                    {
                        BuildListWalk(next, delegateFI, keyFI, nextFI);
                    }
                }
            }
    
            public void Resume()
            {
                if (_handlers == null)
                    throw new ApplicationException("Events have not been suppressed.");
    
                foreach (KeyValuePair<object, Delegate[]> pair in _handlers)
                {
                    for (int x = 0; x < pair.Value.Length; x++)
                        _sourceEventHandlerList.AddHandler(pair.Key, pair.Value[x]);
                }
    
                _handlers = null;
            }
    
            public void Suppress()
            {
                if (_handlers != null)
                    throw new ApplicationException("Events are already being suppressed.");
    
                BuildList();
    
                foreach (KeyValuePair<object, Delegate[]> pair in _handlers)
                {
                    for (int x = pair.Value.Length - 1; x >= 0; x--)
                        _sourceEventHandlerList.RemoveHandler(pair.Key, pair.Value[x]);
                }
            }
    
        }
    }
    
    0 讨论(0)
  • 2020-11-22 02:00

    I found a solution on the MSDN forums. The sample code below will remove all Click events from 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]);
        }
    }
    
    0 讨论(0)
  • 2020-11-22 02:00

    Accepted answer is not full. It doesn't work for events declared as {add; remove;}

    Here is working 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;
    }
    
    0 讨论(0)
提交回复
热议问题