কীভাবে কোনও ইভেন্ট থেকে সমস্ত ইভেন্ট হ্যান্ডলারগুলি সরিয়ে ফেলা যায়


366

একটি নিয়ন্ত্রণে একটি নতুন ইভেন্ট হ্যান্ডলার তৈরি করতে আপনি এটি করতে পারেন

c.Click += new EventHandler(mainFormButton_Click);

অথবা এটা

c.Click += mainFormButton_Click;

এবং ইভেন্ট হ্যান্ডলারটি সরাতে আপনি এটি করতে পারেন

c.Click -= mainFormButton_Click;

তবে কীভাবে আপনি কোনও ইভেন্ট থেকে সমস্ত ইভেন্ট হ্যান্ডলারগুলি সরাবেন?


10
যদি কেউ এখানে ডাব্লুপিএফ সমাধান সন্ধান করতে আসে, আপনি এই উত্তরটি দেখতে চাইতে পারেন ।
ডগলাস

1
আপনি কি সেট করতে পারবেন না c.Click = null?
আলেক্সানিয়া

এটি হ'ল আমি হাস্যকরভাবে অত্যধিক জটিল বলে মনে করি। একটি সহজClear পদ্ধতি দৃশ্যত খুব বেশি প্রচেষ্টা ছিল
9

উত্তর:


167

আমি এমএসডিএন ফোরামে একটি সমাধান পেয়েছি । নীচের নমুনা কোড সমস্ত মুছে ফেলবেClick থেকে ইভেন্ট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]);
        }
    }
}

যদি বাটন 1 নালিতে সেট করা থাকে, সমস্ত ইভেন্ট হ্যান্ডলারগুলি কী বোতাম 1 এর সাথে সংযুক্ত আছে? ক্লিক করুন সঠিকভাবে?
দামিয়েন

3
আমাকে সঠিক যদি আমি ভুল কিন্তু প্রথম লাইন উচিত না RemoveClickEventসমেত শুরু করুন: FieldInfo f1 = typeof(Button)? আমি GetFieldযদি ব্যবহার করি তবে তা বাতিল করব Control
রক্ষক এক

2
এটি সরঞ্জামস্ট্রিপবটনের জন্য কাজ করে বলে মনে হচ্ছে না। আমি টুলস্ট্রিপবটনের সাহায্যে অপসারণ ক্লিকএভেন্টে বাটনটি প্রতিস্থাপন করেছি, তবে সরান ক্লিক ক্লিক করার পরেও ইভেন্টগুলি এখনও রয়েছে। কারও কি এই সমস্যার সমাধান আছে?
স্কাল্লি

1
এমএসডিএন-এর উপরের লিঙ্কটি আমারবটন চেষ্টা করার পরামর্শ দেয় lick ক্লিক করুন + = নাল; আপনি যদি সমস্ত প্রতিনিধি অপসারণ করতে চান (
ক্লিকের

1
@hello_earth এর জন্য কাজ করছে বলে মনে হচ্ছে নাObservableCollection.CollectionChanged += null;
মাইক ডি ক্লার্ক

146

আপনারা এই উপায়টি নিজের উপর খুব শক্ত করে তুলছেন। এটি সহজ:

void OnFormClosing(object sender, FormClosingEventArgs e)
{
    foreach(Delegate d in FindClicked.GetInvocationList())
    {
        FindClicked -= (FindClickedHandler)d;
    }
}

57
আপনি যদি ইভেন্টটির মালিক হন তবে এটি কাজ করবে। এটি একটি নিয়ন্ত্রণে করার চেষ্টা করুন।
ডিলিয়ান

226
... এবং আপনি যদি ইভেন্টটির মালিক হন তবে আপনি কেবল এটি লিখতে পারেন FindClicked = null;যা বরং সহজ।
জন স্কিটি

79
ফাইন্ড ক্লিক করা কী?
লেভিটিকন

3
এটি কিনেক্ট ইভেন্টগুলির জন্য কাজ করে না - kinect.ColorFrameReady -= MyEventHanderকরে, তবে GetInvocationList()তাদের প্রতিনিধিদের উপর পুনরাবৃত্তি করার জন্য আত্মীয়তার উদাহরণগুলির কোনও পদ্ধতি নেই ।
ব্রেন্ট ফাউস্ট

GetInvocationListখুঁজে পাওয়া যায় নি।
জোক হুয়াং

75

সমস্ত ইভেন্ট হ্যান্ডলার অপসারণ থেকে :

সরাসরি না, বড় অংশ হিসাবে আপনি কেবল ইভেন্টটি বাতিল করতে পারবেন না।

অপ্রত্যক্ষভাবে, আপনি আসল ঘটনাটি ব্যক্তিগত করতে এবং চারপাশে এমন একটি সম্পত্তি তৈরি করতে পারেন যা এতে প্রতিনিধিদের যুক্ত / বিয়োগ করা সমস্ত ট্র্যাক করে।

নিম্নলিখিত নিন:

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

4
আমি ভেবেছিলাম যে ওপি সাধারণ। নেট নিয়ন্ত্রণগুলি উল্লেখ করছে .. যাতে এই ধরণের মোড়ানো সম্ভব নাও হতে পারে।
গিশু

4
আপনি নিয়ন্ত্রণটি পেতে পারেন, তারপরে এটি হবে
টম ফোবিয়ার

এটি দুটি তালিকা বজায় রাখে, তালিকাটিতে অ্যাক্সেসের জন্য পুনরায় সেট করতে স্ট্যাকওভারফ্লো / প্রশ্নগুলি / 91778 /… দেখুন বা স্ট্যাকওভারফ্লো.com / প্রশ্নগুলি / 91778/… দেখুন
টিএন

63

গৃহীত উত্তর পূর্ণ নয়। এটি {যোগ হিসাবে ঘোষিত ইভেন্টগুলির জন্য কাজ করে না; অপসারণ;}

এখানে কোড চলছে:

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

4
এই সংস্করণটি আমার পক্ষে কাজ করছিল। স্বীকৃত সংস্করণটি কাজ করে না। তার জন্য +1।
মিস্টার শ্নিটসেল

1
আমি BindingFlags.Publicপ্রথম GetFieldকলটিতে ব্যবহার না করা পর্যন্ত ডাব্লুপিএফ ইভেন্টগুলির জন্য কাজ করি নি ।
লেনার্ট

40

এটি অ-বিদ্যমান ইভেন্ট হ্যান্ডলার মোছার জন্য কোনও ক্ষতি করে না। সুতরাং যদি আপনি জানেন কী কী হ্যান্ডলারগুলি থাকতে পারে তবে আপনি কেবল সেগুলি সব মুছতে পারেন। আমার সবেমাত্র একই রকম ঘটনা ঘটেছে। এটি কিছু ক্ষেত্রে সহায়তা করতে পারে।

ভালো লেগেছে:

// Add handlers...
if (something)
{
    c.Click += DoesSomething;
}
else
{
    c.Click += DoesSomethingElse;
}

// Remove handlers...
c.Click -= DoesSomething;
c.Click -= DoesSomethingElse;

16

আমি আসলে এই পদ্ধতিটি ব্যবহার করছি এবং এটি পুরোপুরি কার্যকর হয়। আমি এখানে অয়নহ্যাকের দ্বারা লিখিত কোডটি দ্বারা 'অনুপ্রাণিত' হয়েছি ।

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

ক্ষেত্রটি MyEventEvent লুকানো থাকলেও এটি বিদ্যমান।

ডিবাগিং, আপনি দেখতে পাচ্ছেন কীভাবে d.targetবস্তুটি ইভেন্টটি পরিচালনা করছে এবং andd.method এর পদ্ধতিটি। আপনাকে কেবল এটি অপসারণ করতে হবে।

এটি দুর্দান্ত কাজ করে। ইভেন্ট হ্যান্ডলারের কারণে আর কোনও জিনিস GC'ed হচ্ছে না।


2
অন্যান্য ভাষায় উত্তর লিখবেন না দয়া করে।
হিল

10

আমি এখানে প্রদর্শিত কোনও সম্পূর্ণ সমাধানকে ঘৃণা করেছি, আমি একটি মিশ্রণ করেছি এবং এখন পরীক্ষা করেছি, যে কোনও ইভেন্ট হ্যান্ডলারের পক্ষে কাজ করেছি:

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

সহজ! স্টিফেন পুনাকের জন্য ধন্যবাদ

আমি এটি ব্যবহার করেছি কারণ আমি প্রতিনিধিদের অপসারণের জন্য জেনেরিক স্থানীয় পদ্ধতি ব্যবহার করি এবং স্থানীয় প্রতিনিধিদের বিভিন্ন মামলার পরে ডেকে আনা হয়, যখন বিভিন্ন প্রতিনিধি নির্ধারিত হয়।


4

আপনি যদি পুনরায় এটি করতে হয় ... এটি করতে প্রতিবিম্ব এবং বেশ কিছুটা সময় লাগবে। ইভেন্ট হ্যান্ডলারগুলি একটি নিয়ন্ত্রণের মধ্যে ইভেন্ট-প্রতিনিধি-মানচিত্রে পরিচালিত হয়। আপনার দরকার হবে

  • নিয়ন্ত্রণ উদাহরণে এই মানচিত্রটি প্রতিফলিত করুন এবং পান।
  • প্রতিটি ইভেন্টের জন্য স্বীকৃত, প্রতিনিধি পান
    • প্রতিটি প্রতিনিধি পালাক্রমে ইভেন্ট হ্যান্ডলারের একটি শৃঙ্খলিত সিরিজ হতে পারে। সুতরাং ওবকন্ট্রোলকে কল করুন em রিমুওহ্যান্ডলার (ইভেন্ট, হ্যান্ডলার)

সংক্ষেপে, অনেক কাজ। তত্ত্বের ক্ষেত্রে এটি সম্ভব ... আমি এর আগে কখনও চেষ্টা করিনি।

নিয়ন্ত্রণের সাবস্ক্রাইব-সাবস্ক্রাইব পর্যায়ে আপনার আরও ভাল নিয়ন্ত্রণ / শৃঙ্খলা থাকতে পারে কিনা তা দেখুন।


3

স্টিফেন ঠিক আছে। এটা খুব সহজ:

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

38
Godশ্বর, সংকলককে এই জাতীয় পরিবর্তনশীল নামগুলি নিষিদ্ধ করা উচিত। ফরাসী ভাষায় গ্রাফ_মাস্ট_বে_ড্রেইন
gracchus

4
ফরাসি থেকে অনুবাদ করা foreach (EventHandler<MyCompletedArgs> handler in CompletionCompleted.GetInvocationList()) { CompletionCompleted -= handler; }
অ্যান্টন কে

@ অ্যানটোনকের ইংরেজি অনুবাদ ভাল কাজ করে। সম্পত্তি হ্যান্ডলারের শূন্যতা পরীক্ষা করতে ভুলবেন না।
ব্রেট

2

একটি উইনফোর্ডস নিয়ন্ত্রণের সম্পত্তি নির্ধারণের সময় আমি কীভাবে ইভেন্টগুলি স্থগিত করতে পারি তা সবেমাত্র পেয়েছি । এটি নিয়ন্ত্রণ থেকে সমস্ত ইভেন্ট সরিয়ে ফেলবে:

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

    }
}

1
এটি খুব সহায়ক ছিল, তবে একটি জিনিস যা পরিবর্তিত হওয়া দরকার: রেজ্যুমে () এ, আপনি হ্যান্ডলারগুলিকে বিপরীত ক্রমে যুক্ত করছেন (আমি ধরে নিচ্ছি এটি দমন থেকে একটি অনুলিপি / পেস্ট হয়েছে, যেখানে আপনি পিছনের দিকে কাজ করতে চান তাই আপনি যে পুনরুক্তি করছেন তার কোনও সংগ্রহের সাথে গোলমাল না করার জন্য)। কিছু কোড হ্যান্ডলারের একটি নির্দিষ্ট অর্ডারে গুলি চালানো গণনা করে, তাই এর সাথে কোনওরকম গণ্ডগোল করা উচিত নয়।
মাইকেল

1

কি দারুন. আমি এই সমাধানটি খুঁজে পেয়েছি, তবে আমার ইচ্ছামতো কিছুই হয়নি। তবে এটি এত ভাল:

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

এটি পূর্ববর্তী উত্তরের চেয়ে অবশ্যই আরও সুন্দর। এটা কি ঠিক একই জিনিস করে? দেখে মনে হচ্ছে এটির মতো, তবে সম্ভবত আমি কিছু মিস করছি। এছাড়াও, যখন আপনি চান সমস্ত ইভেন্টহ্যান্ডলারলিস্ট আপনার কেন একটি নতুন অবজেক্ট তৈরি করা দরকার? ইভেন্টহ্যান্ডলারলিস্টের জন্য কি কোনও সি-টর অ্যাক্সেসযোগ্য নয়, যেমন কোনও অংশের জন্য অভ্যন্তরীণভাবে তৈরি করা কেবল একটিই পেতে পারেন?
মাইকেল

1

এই পৃষ্ঠাটি আমাকে অনেক সাহায্য করেছে। আমি যে কোডটি এখান থেকে পেয়েছি তা হ'ল একটি বোতাম থেকে ক্লিক ইভেন্ট সরানো। আমার কিছু প্যানেল থেকে ডাবল ক্লিক ইভেন্টগুলি মুছতে হবে এবং কয়েকটি বোতাম থেকে ইভেন্টগুলি ক্লিক করতে হবে। সুতরাং আমি একটি নিয়ন্ত্রণ এক্সটেনশান করেছি, যা নির্দিষ্ট ইভেন্টের জন্য সমস্ত ইভেন্ট হ্যান্ডলারকে সরিয়ে দেবে।

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 T target, string eventName) where T:Control
    {
        if (ReferenceEquals(target, null)) throw new NullReferenceException("Argument \"target\" may not be null.");
        FieldInfo fieldInfo = typeof(Control).GetField(eventName, BindingFlags.Static | BindingFlags.NonPublic);
        if (ReferenceEquals(fieldInfo, null)) throw new ArgumentException(
            string.Concat("The control ", typeof(T).Name, " does not have a property with the name \"", eventName, "\""), nameof(eventName));
        object eventInstance = fieldInfo.GetValue(target);
        PropertyInfo propInfo = typeof(T).GetProperty("Events", BindingFlags.NonPublic | BindingFlags.Instance);
        EventHandlerList list = (EventHandlerList)propInfo.GetValue(target, null);
        list.RemoveHandler(eventInstance, list[eventInstance]);
    }
}

এখন, এই এক্সটেনশন ব্যবহার। যদি আপনাকে কোনও বোতাম থেকে ক্লিক ইভেন্টগুলি সরানোর প্রয়োজন হয়,

Button button = new Button();
button.RemoveEvents(nameof(button.EventClick));

যদি আপনাকে কোনও প্যানেল থেকে ডাবলক্লিক ইভেন্টগুলি সরানোর প্রয়োজন হয়,

Panel panel = new Panel();
panel.RemoveEvents(nameof(panel.EventDoubleClick));

আমি সি # তে কোনও বিশেষজ্ঞ নই, সুতরাং কোনও বাগ থাকলে দয়া করে আমাকে ক্ষমা করুন এবং দয়া করে আমাকে এটি সম্পর্কে জানান let


1
.CastTo <> () এক্সটেনশন পদ্ধতিটি ঠিক কোথায় পাওয়া গেছে?
ইব্রার মমতাজ

আপনি কেবল নিজের লিখতে পারেন: পাবলিক স্ট্যাটিক টি কাস্টটো <টি> (এই অবজেক্ট অবজেক্টটোকাস্ট) {রিটার্ন (টি) অবজেক্টটোকাস্ট; }
কিংঅফ হাইপোক্রিটিস

0

কখনও কখনও আমাদের তৃতীয় পক্ষের নিয়ন্ত্রণগুলির সাথে কাজ করতে হয় এবং আমাদের এই বিশ্রী সমাধানগুলি তৈরি করতে হবে। @ অনুপ মুরালিধরন উত্তরের ভিত্তিতে আমি এই সমাধানটি ইনফারেন্স টাইপ এবং টুলস্ট্রিপআইটেম সমর্থন দিয়ে তৈরি করেছি

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

এবং আপনি এটি এটি ব্যবহার করতে পারেন

    var toolStripButton = new ToolStripButton();
    toolStripButton.RemoveItemEvents("EventClick");

    var button = new Button();
    button.RemoveControlEvents("EventClick");

0

আমি ডগলাস দ্বারা আর একটি কাজের সমাধান খুঁজে পেয়েছি

এই পদ্ধতিটি সমস্ত ইভেন্ট হ্যান্ডলারগুলি সরিয়ে দেয় যা কোনও উপাদানের উপর নির্দিষ্ট রুট ইভেন্টে সেট করা থাকে।
এটি ব্যবহার করুন

Remove_RoutedEventHandlers(myImage, Image.MouseLeftButtonDownEvent);

সম্পূর্ণ কোড:

/// <summary>
/// Removes all event handlers subscribed to the specified routed event from the specified element.
/// </summary>
/// <param name="element">The UI element on which the routed event is defined.</param>
/// <param name="RoutetEvent_ToRemove">The routed event for which to remove the event handlers.</param>
public static void RemoveRoutedEventHandlers(UIElement UIElement_Target, RoutedEvent RoutetEvent_ToRemove)
{
    // Get the EventHandlersStore instance which holds event handlers for the specified element.
    // The EventHandlersStore class is declared as internal.
    PropertyInfo PropertyInfo_EventHandlersStore = typeof(UIElement).GetProperty(
        "EventHandlersStore", BindingFlags.Instance | BindingFlags.NonPublic);
    object oEventHandlersStore = PropertyInfo_EventHandlersStore.GetValue(UIElement_Target, null);

    // If there's no event handler subscribed, return
    if (oEventHandlersStore == null) return;

    // Invoke the GetRoutedEventHandlers method on the EventHandlersStore instance 
    // for getting an array of the subscribed event handlers.
    MethodInfo MethodInfo_RoutedEventHandlers = oEventHandlersStore.GetType().GetMethod(
        "GetRoutedEventHandlers", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
    RoutedEventHandlerInfo[] RoutedEventHandlerInfos = (RoutedEventHandlerInfo[])MethodInfo_RoutedEventHandlers.Invoke(
        oEventHandlersStore, new object[] { RoutetEvent_ToRemove });

    // Iteratively remove all routed event handlers from the element.
    foreach (RoutedEventHandlerInfo RoutedEventHandlerInfo_Tmp in RoutedEventHandlerInfos)
        UIElement_Target.RemoveHandler(RoutetEvent_ToRemove, RoutedEventHandlerInfo_Tmp.Handler);
}

0

বোতামের জন্য সমস্ত হ্যান্ডলারগুলি সরিয়ে দেয়: 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();
    }
}

-1

ঠিক আছে, এখানে বিযুক্ত ঘটনা অপসারণের আরও একটি সমাধান রয়েছে (যদি আপনার কাছে ইতিমধ্যে নিয়ন্ত্রণের জন্য ইভেন্টগুলি পরিচালনা করার পদ্ধতি থাকে):

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.মাউসডাউন - = ডেলিগেট করতে পারেন re সুতরাং এটি কোন সমস্যার সমাধান করতে সহায়তা করবে না কোনটি কী ডেলিগেটকে অপসারণ করা উচিত তা বিশেষত যদি তারা ইনলাইন থাকে।
সফটলিয়ন

-1

এটি ওপি-র কোনও উত্তর নয়, তবে আমি ভেবেছিলাম যে এটি অন্যকে সহায়তা করতে পারে যদি আমি এখানে এটি পোস্ট করি।

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

-3

আমি এই উত্তরটি পেয়েছি এবং এটি আমার প্রয়োজনীয়তার সাথে প্রায় ফিট করে। ক্লাসের জন্য SwDevMan81 ধন্যবাদ। স্বতন্ত্র পদ্ধতিগুলির দমন ও পুনঃসারণের অনুমতি দেওয়ার জন্য আমি এটিকে সংশোধন করেছি এবং আমি ভেবেছিলাম এটি এখানে পোস্ট করব।

// 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's 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);
                    }
                }
            }
        }
    } 
}

8
এটি একটি বিভ্রান্তিকর সমাধান এবং শিল্প গ্রেড সফ্টওয়্যারটিতে কখনও ব্যবহার করা উচিত নয়। সর্বোত্তম পদ্ধতির উল্লেখ করা আছে: আপনার ইভেন্টের সাবস্ক্রিপশন এবং আন-সাবস্ক্রিপশন ভালভাবে পরিচালনা করুন এবং আপনি কখনও এ জাতীয় সমস্যার মুখোমুখি হবেন না।
ত্রি কিউ ট্রান

আমি সম্মত হই যে আমাদের ইভেন্টগুলি আনওয়্যার করতে প্রতিবিম্বটি ব্যবহার করা উচিত নয়, এবং ইভেন্ট সাবস্ক্রিপশন এবং আন-সাবস্ক্রিপশন অ্যাপ্লিকেশন দ্বারা পরিচালনা করা উচিত। আমি মনে করি বিতর্কিত ইস্যুটি ডিইবিইউজি সময়ে ব্যবহার করা উচিত, আমরা কীভাবে কিছু উপদ্রব করছি তা সন্ধান করতে। আপনি রিফ্যাক্টর করছেন এমন উত্তরাধিকার অ্যাপ্লিকেশনগুলির জন্য এটি আবশ্যক।
টিয়াগো ফ্রেইটাস লিয়াল
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.