简体   繁体   English

自定义参数未删除的事件处理程序

[英]Event Handler With Custom Parameters Not Removing

I am adding a custom event to a DataGridView to handle cell clicks. 我将自定义事件添加到DataGridView以处理单元格单击。 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. 我首先尝试删除以前的事件处理程序,因为我每次都发送相同的DataGridView并填充它。

//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). 我的问题是,当它第二次运行并且SourceObject已更改时,该事件仍然具有原始的SourceObject发送给它(我相信永远不会删除原始的句柄)。

I need to dynamically remove all CellClick events (or even all, there aren't that many). 我需要动态删除所有CellClick事件(甚至全部,没有那么多)。

Maybe "this", when you are calling the second time the -= operator, is a different object than the first time you executed the +=. 第二次调用-=运算符时,也许“ this”与第一次执行+ =时是不同的对象。 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);

    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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