Bir hadisə içərisində bütün hadisə işleyicilerinin necə qaldırılacağı

Bir nəzarətdə yeni bir hadisə işləyicisi yaratmaq üçün bunu edə bilərsiniz.

 c.Click += new EventHandler(mainFormButton_Click); 

və ya

 c.Click += mainFormButton_Click; 

və bunu edə biləcəyiniz bir hadisə işleyicisini qaldırmaq üçün

 c.Click -= mainFormButton_Click; 

Ancaq bütün hadisə işleyicilerini bir hadisədən necə çıxarmaq olar?

304
18 сент. Carrick tərəfindən müəyyən Sep 18 2008-09-18 14:34 '08 at 14:34 2008-09-18 14:34
@ 16 cavab

MSDN forumlarında həll tapdım. Aşağıdakı nümunə kodu, button1 bütün Click hadisələrini aradan qaldıracaq.

 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]); } } } 
148
18 сент. cavab xsl 18 sep verilir . 2008-09-18 14:53 '08 at 2:53 pm 2008-09-18 14:53

Sizlər bu PATHı çox sevirsiniz. Bu asan:

border=0
 void OnFormClosing(object sender, FormClosingEventArgs e) { foreach(Delegate d in FindClicked.GetInvocationList()) { FindClicked -= (FindClickedHandler)d; } } 
114
29 марта '11 в 18:59 2011-03-29 18:59 Cavab Stephen Punak tərəfindən 29 Mart 2011 tarixində saat 18: 59-da verilmişdir

Bütün hadisə işleyicilerini sil :

Birbaşa deyil, əsasən hadisəni null üçün təyin edə bilməzsiniz.

Dolayısı ilə hadisəni özəlləşdirə və onun ətrafında mülk yaratmaq üçün bütün nümayəndələri əvvəllər əlavə edilərkən / çıxardıqları təqdirdə izləyə bilərlər.

Aşağıdakıları edin:

 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(); } 
63
18 сент. Jorge Ferreira tərəfindən verilmiş cavab Sep 18 2008-09-18 14:40 '08 at 2:40 pm 2008-09-18 14:40

Qəbul edilən cavab tamamlanmadı. {Add; elan edilmiş hadisələr üçün işləmir; silmək;

İş kodu:

 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) {  field = type.GetField(eventName, BindingFlags.Static | BindingFlags.Instance | BindingFlags.NonPublic); if (field != null  (field.FieldType == typeof(MulticastDelegate) || field.FieldType.IsSubclassOf(typeof(MulticastDelegate)))) break;  field = type.GetField("EVENT_" + eventName.ToUpper(), BindingFlags.Static | BindingFlags.Instance | BindingFlags.NonPublic); if (field != null) break; type = type.BaseType; } return field; } 
46
13 нояб. Cavab LionSoft tərəfindən verilir. 2011-11-13 01:38 '11 at 1:38 2011-11-13 01:38

Bu, mövcud olmayan bir hadisə işlətməsinin qaldırılmasına zərər vermir. Buna görə, hansı işleyicilerin ola biləcəyini bilsəniz, sadəcə bunların hamısını silin. Bənzər bir vəziyyətim vardı. Bəzi hallarda bu kömək edə bilər.

Kimi

 // Add handlers... if (something) { c.Click += DoesSomething; } else { c.Click += DoesSomethingElse; } // Remove handlers... c.Click -= DoesSomething; c.Click -= DoesSomethingElse; 
33
23 июня '09 в 15:22 2009-06-23 15:22 Cavab MdMx tərəfindən 23 İyun '09 saat 15:22 'də 2009-06-23 15:22' də verilir

Mən bu üsuldan istifadə edirəm və çox yaxşı işləyirəm. Burada Aeonhack tərəfindən yazılan kodla mən "ilhamlandırdım".

16
04 дек. Cavab Ivan Ferrer Villa verildi 04 Dekabr. 2010-12-04 08:07 '10 at 8:07 2010-12-04 08:07

Bunu mütləq yerinə yetirmək lazımdırsa ... bunun əksinə bir müddət və bir müddət olacaq. Hadisə işleyicileri bir hadisə xəritəsində idarə olunur - nəzarət içində nümayəndə. Lazımdır

  • Flip və nəzarət xəritəsi bir nümunə bu xəritəsi almaq.
  • Hər bir hadisə üçün nümayəndəliyin alınması
    • hər bir nümayəndə, öz növbəsində, müxtəlif hadisə işləyiciləri ola bilər. Buna görə, obControl.RemoveHandler (hadisə, işleyici)

Bir sözlə, bir çox iş. Bu nəzəriyyədə mümkündür ... Mən bu kimi bir şeyi heç vaxt sınamışam.

Nəzarət üçün abunə-ləğv abunəliyində nəzarət / intizamın yaxşılaşdırılmasına baxın.

5
18 сент. Gişu tərəfindən verilmiş cavab 18 sentyabr 2008-09-18 14:45 '08 at 2:45 pm 2008-09-18 14:45

Stephen sağdır. Çox sadədir:

 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; } } } 
4
22 апр. Mmike tərəfindən verilmiş cavab 22 aprel 2011-04-22 13:58 '11 at 13:58 2011-04-22 13:58

Yalnız bir WinForms nəzarət xüsusiyyətini təyin edərkən hadisələri durdurmaq üçün necə tapdım. Bütün hadisələri nəzarətdən çıxaracaq:

 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]); } } } } 
3
21 окт. Cavab SwDevMan81 21 oktyabr tərəfindən verilir . 2009-10-21 00:11 '09 at 0:11 2009-10-21 00:11

Vay. Mən bu həllini tapdım, ancaq istədiyim kimi işə yaramadı. Amma çox yaxşıdır:

 EventHandlerList listaEventos; private void btnDetach_Click(object sender, EventArgs e) { listaEventos = DetachEvents(comboBox1); } private void btnAttach_Click(object sender, EventArgs e) { AttachEvents(comboBox1, listaEventos); } public EventHandlerList DetachEvents(Component obj) { object objNew = obj.GetType().GetConstructor(new Type[] { }).Invoke(new object[] { }); PropertyInfo propEvents = obj.GetType().GetProperty("Events", BindingFlags.NonPublic | BindingFlags.Instance); EventHandlerList eventHandlerList_obj = (EventHandlerList)propEvents.GetValue(obj, null); EventHandlerList eventHandlerList_objNew = (EventHandlerList)propEvents.GetValue(objNew, null); eventHandlerList_objNew.AddHandlers(eventHandlerList_obj); eventHandlerList_obj.Dispose(); return eventHandlerList_objNew; } public void AttachEvents(Component obj, EventHandlerList eventos) { PropertyInfo propEvents = obj.GetType().GetProperty("Events", BindingFlags.NonPublic | BindingFlags.Instance); EventHandlerList eventHandlerList_obj = (EventHandlerList)propEvents.GetValue(obj, null); eventHandlerList_obj.AddHandlers(eventos); } 
2
27 июля '12 в 16:38 2012-07-27 16:38 Cavab Sergio Cabral tərəfindən verilib 27 iyul '4 saat 04:38 pm 2012-07-27 16:38

Burada göstərilən hər hansı bir kompleks həlldən nifrət etdim, bir qarışdırdıq və indi test etdik, hər hansı bir hadisə işçisi üçün çalışdı:

 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! Stephen Punak üçün təşəkkür edirik.

Mən nümayəndələri aradan qaldırmaq üçün ümumi bir lokal metoddan istifadə etdiyim üçün istifadə etdim və müxtəlif üsullar təyin edildikdə müxtəlif üsullardan sonra yerli üsul çağırılır.

1
21 июля '16 в 17:19 2016-07-21 17:19 Cavab Vinicius Schneider tərəfindən 21 İyul, 'da 17:19 2016-07-21 17:19' də verilir

Bəzən biz ThirdParty nəzarəti ilə işləmək məcburiyyətindəyik və bu həssas həllər yaratmalıyıq. Cavabına əsasən @Anoop Muraleedharan, mən bu həlli çıxış növü və ToolStripItem dəstəyi ilə yaradılmışdır

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

Və bu kimi istifadə edə bilərsiniz:

  var toolStripButton = new ToolStripButton(); toolStripButton.RemoveItemEvents("EventClick"); var button = new Button(); button.RemoveControlEvents("EventClick"); 
0
16 сент. Cavab Jhonattan 16 sep verilir . 2016-09-16 20:50 '16 saat 20:50 'da 2016-09-16 20:50

Bəli, əlaqəli hadisə silmək üçün başqa bir həll var (əgər artıq nəzarət üçün hadisələri idarə etmək üçün bir yol var):

 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); 
-1
26 окт. Cavab 26 oktyabr suso verilir . 2011-10-26 10:05 '11 saat 10:05 'da 2011-10-26 10:05

Bu, OP-ə cavab deyil, amma başqalarına kömək edə biləcəyini düşünürdüm.

  /// <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); } 
-1
29 июня '15 в 14:43 2015-06-29 14:43 Cavab RenniePet tərəfindən verilir 29 iyun, '15 də 14:43 2015-06-29 14:43

Bu səhifə mənə çox kömək etdi. Buradan aldığım kod, tıklamanın düyməsini çıxarmaq üçün nəzərdə tutulmuşdur. Bəzi panellərdən ikiqat klik hadisələrini aradan qaldırmalı və bəzi düymələrdən hadisələrə vurmalıyam. Beləliklə, müəyyən bir hadisə üçün bütün hadisə işleyicilerini aradan qaldıracaq bir nəzarət uzantısı yaratdım.

 using System; using System.Collections.Generic; using System.ComponentModel; using System.Drawing; using System.Windows.Forms; using System.Reflection; public static class EventExtension { public static void RemoveEvents<T>(this Control target,string Event) { FieldInfo f1 = typeof(Control).GetField(Event,BindingFlags.Static | BindingFlags.NonPublic); object obj = f1.GetValue(target.CastTo<T>()); PropertyInfo pi = target.CastTo<T>().GetType().GetProperty("Events", BindingFlags.NonPublic | BindingFlags.Instance); EventHandlerList list = (EventHandlerList)pi.GetValue(target.CastTo<T>(), null); list.RemoveHandler(obj, list[obj]); } } 

İndi, bu extenstion istifadə edin. Bir klik hadisəsindən bir düymədən çıxarmaq istəyirsinizsə,

 Button button = new Button(); button.RemoveEvents<Button>("EventClick"); 

Hadisələri silmək üçün paneldə cüt kliklə,

 Panel panel = new Panel(); panel.RemoveEvents<Panel>("EventDoubleClick"); 

Mən C #-də mütəxəssis deyiləm, buna görə də hər hansı bir səhv varsa, məni bağışla və xahiş edirəm mənə bu barədə məlumat verin.

-1
04 апр. Anoop Muraleedharan tərəfindən verilmiş cavab 04 Apr 2011-04-04 11:53 '11 at 11:53 2011-04-04 11:53

Bu cavabı tapdım və demək olar ki, mənim ehtiyaclarımla uyğunlaşdı. Sinif üçün SwDevMan81 sayəsində. Mən fərdi metodların basdırılmasına və yenidən başlamasına icazə vermək üçün dəyişdim və mən burada yerləşdirdiyimi düşündüm.

 // This class allows you to selectively suppress event handlers for controls. You instantiate // the suppressor object with the control, and after that you can use it to suppress all events // or a single event. If you try to suppress an event which has already been suppressed // it will be ignored. Same with resuming; you can resume all events which were suppressed, // or a single one. If you try to resume an un-suppressed event handler, it will be ignored. //cEventSuppressor _supButton1 = null; //private cEventSuppressor SupButton1 { // get { // if (_supButton1 == null) { // _supButton1 = new cEventSuppressor(this.button1); // } // return _supButton1; // } //} //private void button1_Click(object sender, EventArgs e) { // MessageBox.Show("Clicked!"); //} //private void button2_Click(object sender, EventArgs e) { // SupButton1.Suppress("button1_Click"); //} //private void button3_Click(object sender, EventArgs e) { // SupButton1.Resume("button1_Click"); //} using System; using System.Collections.Generic; using System.Text; using System.Reflection; using System.Windows.Forms; using System.ComponentModel; namespace Crystal.Utilities { public class cEventSuppressor { Control _source; EventHandlerList _sourceEventHandlerList; FieldInfo _headFI; Dictionary<object, Delegate[]> suppressedHandlers = new Dictionary<object, Delegate[]>(); PropertyInfo _sourceEventsInfo; Type _eventHandlerListType; Type _sourceType; public cEventSuppressor(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 Dictionary<object, Delegate[]> BuildList() { Dictionary<object, Delegate[]> retval = 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); retval = BuildListWalk(retval, head, delegateFI, keyFI, nextFI); } return retval; } private Dictionary<object, Delegate[]> BuildListWalk(Dictionary<object, Delegate[]> dict, 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); if (dele != null) { Delegate[] listeners = dele.GetInvocationList(); if (listeners != null  listeners.Length > 0) { dict.Add(key, listeners); } } if (next != null) { dict = BuildListWalk(dict, next, delegateFI, keyFI, nextFI); } } return dict; } public void Resume() { } public void Resume(string pMethodName) { //if (_handlers == null) // throw new ApplicationException("Events have not been suppressed."); Dictionary<object, Delegate[]> toRemove = new Dictionary<object, Delegate[]>(); // goes through all handlers which have been suppressed. If we are resuming, // all handlers, or if we find the matching handler, add it back to the // control event handlers foreach (KeyValuePair<object, Delegate[]> pair in suppressedHandlers) { for (int x = 0; x < pair.Value.Length; x++) { string methodName = pair.Value[x].Method.Name; if (pMethodName == null || methodName.Equals(pMethodName)) { _sourceEventHandlerList.AddHandler(pair.Key, pair.Value[x]); toRemove.Add(pair.Key, pair.Value); } } } // remove all un-suppressed handlers from the list of suppressed handlers foreach (KeyValuePair<object, Delegate[]> pair in toRemove) { for (int x = 0; x < pair.Value.Length; x++) { suppressedHandlers.Remove(pair.Key); } } //_handlers = null; } public void Suppress() { Suppress(null); } public void Suppress(string pMethodName) { //if (_handlers != null) // throw new ApplicationException("Events are already being suppressed."); Dictionary<object, Delegate[]> dict = BuildList(); foreach (KeyValuePair<object, Delegate[]> pair in dict) { for (int x = pair.Value.Length - 1; x >= 0; x--) { //MethodInfo mi = pair.Value[x].Method; //string s1 = mi.Name; // name of the method //object o = pair.Value[x].Target; // can use this to invoke method pair.Value[x].DynamicInvoke string methodName = pair.Value[x].Method.Name; if (pMethodName == null || methodName.Equals(pMethodName)) { _sourceEventHandlerList.RemoveHandler(pair.Key, pair.Value[x]); suppressedHandlers.Add(pair.Key, pair.Value); } } } } } } 
-3
04 марта '10 в 23:17 2010-03-04 23:17 Cavab Francine tərəfindən 04 Mart '10' da 23:17 'də verildi 2010-03-04 23:17

Tags ilə əlaqədar digər suallar və ya bir sual