3

我正在用 winForm 编写一个应用程序。我在 from1 中有一个面板,它有很多事件处理程序。当我处理 panel1 并创建新面板时,以前的事件存在并且它们会触发。为了删除 panel1 事件,我尝试了下面的代码。

panel1.Click -=  clickHandle_1 ; 

但它并不是在程序代码中的所有地方都有效。例如在另一种方法中。创建新 panel1 时如何删除 panel1 的所有先前事件?

4

4 回答 4

9

据此要取消panel1的所有点击事件,请执行以下操作:

FieldInfo f1 = typeof(Control).GetField("EventClick", BindingFlags.Static| BindingFlags.NonPublic);
object obj = f1.GetValue(panel1);
PropertyInfo pi = panel1.GetType().GetProperty("Events", BindingFlags.NonPublic | BindingFlags.Instance);
EventHandlerList list = (EventHandlerList)pi.GetValue(panel1, null);
list.RemoveHandler(obj, list[obj]);

并且为了取消 panel1 的其他事件,更改EventClick为要删除的事件名称。

可以使用以下代码获取所有事件名称:

EventInfo[] info = type.GetEvents();
for (int i = 0; i < info.Length; i++)
{
   Console.WriteLine(info[i].Name + "\n");
}
于 2013-09-13T09:27:55.550 回答
4

通常,当您Dispose使用对象/控件时,该对象/控件的所有成员(包括)Event handler list也应该被处置且不可用。因此,当您说 时your panel1 is disposed,不可能在已处置的控件上触发任何事件(例如Resize)。您应该检查您是否确实处置了您的面板。这是一种可以用来删除所有Event handlers控件的Reflection方法(类型):DisposeEventsEventHandlerList

public void RemoveHandlerList(Control c){
  EventHandlerList list = (EventHandlerList) typeof(Control).GetProperty("Events", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance).GetValue(c, null);
  typeof(EventHandlerList).GetMethod("Dispose").Invoke(list, null);
}
于 2013-09-13T08:26:42.990 回答
3

一次删除一个:

panel1.Click -= clickHandle_1;

没有一次性取消订阅所有事件处理程序的干净方法。跟踪您订阅的内容并相应地取消订阅。

于 2013-09-12T20:36:40.773 回答
0

不确定这是否可行,但这是我最接近的:

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


    private Dictionary<string, EventHandler> _handlers = new Dictionary<string, EventHandler>();
    TextBox _txt = new TextBox();

    void WireHandlers()
    {

         // get references of your handlers
         EventHandler _hnd1 = delegate { return; }; // here will be your named method. This is only for example
         EventHandler _hnd2 = delegate { return; }; // here will be your named method. This is only for example

         // wire handlers
        _txt.Click += _hnd1;
        _txt.TextChanged  += _hnd2;
         // save wired handler collection
        _handlers.Add("Click", _hnd1);
        _handlers.Add("TextChanged", _hnd2);
    }


    void UnwireHandlers()
    {

        // lets unwire all handlers
        foreach (var kvp in _handlers)
        {
            // inspect keyValuePair - each key corresponds to the name of some event
            switch (kvp.Key)
            {
                case "Click":
                    _txt.Click -= kvp.Value;
                    break;
                case "TextChanged":
                    _txt.TextChanged  -= kvp.Value;
                    break;
                default:
                    throw new Exception("no such handler found");
            }
        }

        _handlers.Clear();
    }

}
于 2013-09-12T22:30:38.890 回答