2013-09-12 3 views
3

Im, пишу приложение в winForm, похожее на плитку Windows 8. Плиты меняют свои позиции, когда меняю размер формы. Моя проблема в том, что у меня есть много обработчиков событий для конкретной панели . & Я не могу удалить их. Это что-то вроде этого:удалите все EventHandlers определенного элемента управления

panel1.Resize += resizeHandle_1; 
panel1.Resize += resizeHandle_2; 
panel1.Resize += resizeHandle_3; 

panel1.Click += clickHandle_1; 
panel1.Click += clickHandle_2; 
panel1.Click += clickHandle_3; 

Когда я выбрасывайте ПАНЕЛЬ1 & я создать новую ПАНЕЛЬ1, существуют предыдущие события !!! & они вызывают !!!

Как удалить предыдущие события, когда я создаю новую панель1 &, где бы я ни захотел в форме1 ??

Я пробовал panel1.Click -= clickHandle_1, но он не работает везде, где в коде. например, другим способом.

+1

Это код запах. Вы могли бы просто написать * one * обработчик событий, который выполняет работу для всех трех. Или просто выведите класс из Panel, который переопределяет методы OnResize и OnClick. Также не ясно, почему вы хотите их удалить, переменную bool можно проверить в обработчике событий, чтобы пропустить все, что он делает. Попытайтесь опубликовать значащий код вместо этого. –

+0

Согласовано. Я бы рассмотрел применение вариации шаблона стратегии здесь. http://www.oodesign.com/strategy-pattern.html – dcastro

+0

Я нашел решение. –

ответ

8

Это проверенный код. оно работает.

Чтобы отменить все кликах из панели1 сделать это:

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]); 

отменить другие события, в первой строке, измените EventClick на то EventResize (или что-то событие, которое вы хотите удалить).

вы можете получить все название события, как это:

EventInfo[] info = type.GetEvents(); 
for (int i = 0; i < info.Length; i++) 
{ 
    Console.WriteLine(info[i].Name + "\n"); 
} 
+1

+1 для интересного 'открытия' на' статических частных полях', вам, возможно, придется искать много? –

+0

да.и искали, как и вы. –

+0

, вы должны были поставить исходный ответ - https://stackoverflow.com/a/91853/2377343 –

3

Удалить их по одному за раз:

panel1.Click -= clickHandle_1; 

Там нет чистого способа отписки всех обработчиков событий сразу. Следите за тем, что вы подписываете, и отмените подписку на них соответствующим образом.

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(); 
    } 

} 
1

Обычно, когда вы Dispose объект/управления, все члены этого объекта/управления, включая Event handler list должны быть расположены слишком и непригодный для использования. Поэтому, когда вы говорите your panel1 is disposed, невозможно заблокировать какое-либо событие на этом удаленном контроле (например, Resize). Вы должны проверить, действительно ли вы используете свою панель. Вот как вы можете использовать, чтобы удалить все Event handlers управления с использованием Reflection для Dispose в (тип EventHandlerList) Events:

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); 
} 
+0

невозможно. Я имею в виду, когда я удаляю panel1 и создаю новый экземпляр, когда я изменяю размер панели, предыдущие события вызывают !! вы можете проверить! –

+0

@AmirHosseinRezaei вы могли бы опубликовать код, показывающий, как вы «уничтожаете» свою панель? –

+0

Ваш код прост. это сработало. Пользуясь королем королем –

Смежные вопросы