使用 lambda 表达式添加的事件处理程序如何移除?

4

我有一个控件,我添加了一个事件。然而,我需要向事件方法传递一些额外的参数,所以我使用了lambda表达式,就像这里描述的那样:

将参数传递给EventHandler

comboBox.DropDown += (sender, e) => populateComboBox(sender, e, dataSource, selectedItem);

但是这个事件应该只在满足条件后第一次触发,之后应该被移除。
这样做是无效的:
comboBox.DropDown -= (sender, e) => populateComboBox(sender, e, dataSource, selectedItem);

所以问题是,有没有一种方法可以删除这个方法?
我看到过这个: 如何从控件中删除所有事件处理程序 但是我无法让它在ComboBox DropDown事件中起作用。

也可能是重复的 https://dev59.com/FnM_5IYBdhLWcg3wfTE0。 - devuxer
1个回答

3

无法移除的问题是因为您在删除时提供了一个新的lambda表达式。您需要保留由Lambda表达式创建的委托引用,以便从控件中删除它。

EventHandler handler = (x, y) => comboBox1_DropDown(x, y);
comboBox1.DropDown += handler;

它将简单地工作如下:
comboBox1.DropDown -= handler;

通过反射:

    private void RemoveEvent(ComboBox b, EventHandler handler)
    {
        EventInfo f1 = typeof(ComboBox).GetEvent("DropDown");
        f1.RemoveEventHandler(b, handler);
    }

这不起作用,因为我需要从事件处理程序本身中删除eventHandler,而这不会将自身作为参数,因为它仍未分配。我可以创建一系列事件,但这比我想要的更加复杂。 - Karlovsky120
1
为什么不将处理程序保持为类成员或在命名缓存中?当您访问它作为成员或缓存引用并满足条件时,就可以将其删除。 - vendettamit
修复了。事先创建了一个带有虚拟方法的处理程序,然后编写了你在那里所做的内容。 - Karlovsky120

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接