简体   繁体   中英

Event Handler With Custom Parameters Not Removing

I am adding a custom event to a DataGridView to handle cell clicks. This needs a parameter passed to it.

I first attempt to delete the previous event handler, as I am sending the same DataGridView in and populating it each time.

//To delete the old handle
        DataGridViewToPopulate.CellClick -= (sender, e) => DataGridView_CellClick(sender, e, SourceObject);    
//To add new handle
        DataGridViewToPopulate.CellClick += (sender, e) => DataGridView_CellClick(sender, e, SourceObject);

My problem is, when this runs the second time, and the SourceObject has changed, the event still has the original SourceObject being sent to it (I believe the original handle is never removed).

I need to dynamically remove all CellClick events (or even all, there aren't that many).

Maybe "this", when you are calling the second time the -= operator, is a different object than the first time you executed the +=. So that -= will not detach that first object, and you would be attaching a second object while not removing the first one.

If that's the case, you should try to find the way to detach that first object.

I was able to find a solution with reflection,

        private static void UnsubscribeOne(object target)
    {

        Delegate[] subscribers;
        Type targetType;
        string EventName = "EVENT_DATAGRIDVIEWCELLCLICK";

        targetType = target.GetType();

        do
        {
            FieldInfo[] fields = targetType.GetFields(BindingFlags.Static | BindingFlags.Instance | BindingFlags.NonPublic);

            foreach (FieldInfo field in fields)
            {

                if (field.Name == EventName)
                {

                    EventHandlerList eventHandlers = ((EventHandlerList)(target.GetType().GetProperty("Events", (BindingFlags.FlattenHierarchy | (BindingFlags.NonPublic | BindingFlags.Instance))).GetValue(target, null)));
                    Delegate d = eventHandlers[field.GetValue(target)];

                    if ((!(d == null)))
                    {

                        subscribers = d.GetInvocationList();

                        foreach (Delegate d1 in subscribers)
                        {

                            targetType.GetEvent("CellClick").RemoveEventHandler(target, d1);

                        }

                        return;
                    }
                }
            }

            targetType = targetType.BaseType;

        } while (targetType != null);

    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM