添加带有参数的事件,但需要再次删除它们

Adding events with parameters but need to remove them again

提问人:PKYNI 提问时间:11/11/2023 最后编辑:Theodor ZouliasPKYNI 更新时间:11/11/2023 访问量:25

问:

因此,在我动态创建对象并传递额外值的表单中,这使用下面的代码工作。我找不到删除实际有效的点击事件的方法。任何人都知道如何在不删除和重新创建新对象的情况下

向控件添加行为:

foreach (Control c in Controls)
{
    if (c.GetType() == typeof(Button) && c.Name.Length == 7)
    {
        c.Enabled = true;

        //add the event handler, passing the optional string in, reading the letter from the name
        c.Click += (sender2, e2) => ButtonClick(sender2, e2, c.Name.Substring(c.Name.Length - 1, 1));
    }
}

尝试使用此代码删除:

c.Click -= ButtonClick;

我还考虑过尝试使用事件处理程序对象来删除它,但无法让它工作。

当我没有将参数传递给方法时,我已经成功地删除了事件,但这会导致其他问题。

如果有人知道如何删除我在上面添加的事件,将不胜感激。

谢谢

C# WinForms 事件处理 参数传递

评论

0赞 jmcilhinney 11/11/2023
您一开始没有添加,因此无法删除 .您添加的是一个调用 的 lambda,因此您需要删除这些内容。如果您需要添加和删除,为什么不首先使用命名方法而不是 lambda?ButtonClickButtonClickButtonClick
0赞 PKYNI 11/11/2023
无法获取使用参数的命名方法。这是有效的代码行
0赞 PKYNI 11/11/2023
在这里找到了解决方案(stackoverflow.com/questions/91778/... )
0赞 jmcilhinney 11/11/2023
如果无法使命名函数正常工作,那是因为您犯了同样的错误,即将事件处理程序与事件处理程序调用的方法混淆。在您发布的代码中,事件处理程序通常只有两个参数。然后,该事件处理程序调用具有三个参数的方法。您可以使用命名方法执行此操作,就像使用 lambda 一样。从一种方法调用另一个方法有什么不明白的地方?

答:

0赞 Theodor Zoulias 11/11/2023 #1

您可以使用本地函数。局部函数是嵌套在另一个方法中的方法。它们只能从其包含方法中调用。例如,下面是一个局部函数:Button_Click

private void Form_Load(object sender, EventArgs e)
{
    void Button_Click(object sender2, EventArgs e2)
    {
        Button button = (Button)sender2;
        button.Click -= Button_Click; // Remove the handler
        string suffix = button.Name.Substring(button.Name.Length - 1, 1);
        DoSomething(button, suffix);
    }

    foreach (Control c in Controls)
    {
        if (c is Button && c.Name.Length == 7)
        {
            c.Click += Button_Click;
            c.Enabled = true;
        }
    }
}
0赞 PKYNI 11/11/2023 #2

使用此处显示的方法找到的解决方案删除所有事件处理程序

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