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

时间:2018-02-13 13:54:27

标签: c# events datagridview

我正在向DataGridView添加自定义事件以处理单元格点击。这个 需要传递给它的参数。

我首先尝试删除以前的事件处理程序,因为我每次都在发送相同的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);

我的问题是,当第二次运行并且SourceObject已更改时,事件仍然会将原始SourceObject发送给它(我相信永远不会删除原始句柄)。

我需要动态删除所有CellClick事件(甚至全部,没有那么多)。

2 个答案:

答案 0 :(得分:0)

当您第二次调用 - =运算符时,可能是“this”,这是与第一次执行+ =时不同的对象。这样 - =不会分离第一个对象,而你将附加第二个对象而不删除第一个对象。

如果是这种情况,您应该尝试找到分离第一个对象的方法。

答案 1 :(得分:0)

我能够找到一个带反射的解决方案,

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

    }