1

我正在制作一个自定义按钮(Winforms 控件库)并具有下面的代码,以便将所有 mouseenter 添加到我的按钮中的所有控件中。当我运行它时,它会导致堆栈溢出异常。我用 Click 而不是 MouseEnter 有相同的代码,它工作正常。这是代码:

public new event EventHandler MouseEnter {
    add
    {
        this.MouseEnter += value;
        foreach (Control i in Controls)
        {
            i.MouseEnter += value;
        }
    }
    remove
    {
        this.MouseEnter -= value;
        foreach (Control i in Controls)
        {
            i.MouseEnter -= value;
        }
    }
}

这是点击代码:

public new event EventHandler Click {
    add {
        this.Click += value;
        foreach (Control i in Controls) {
            i.Click += value;
        }
    }
    remove {
        this.Click -= value;
        foreach (Control i in Controls) {
            i.Click -= value;
        }
    }
}
4

3 回答 3

5

+=是“为此事件调用加法器”的简写。+=你是从你的加法器调用的。因此,您有未绑定的递归,导致堆栈溢出。

查看您的代码,您似乎正在自己定义加法器,以便不仅从控件中添加和删除处理程序,而且还从其所有子项中添加和删除处理程序。这让我觉得这是一个非常糟糕的主意:给定事件的订阅者有合理的期望,即他们只会在实际事件被触发时收到通知,而不是在事件被他们一无所知的任意数量的发布者触发时收到通知。

如果您想创建执行此操作的辅助方法,那可能更有意义,因为现在调用这些方法的消费者确切地知道他们正在进入什么。同样,这将摆脱您启动的递归错误。

最后,这个功能可能是不必要的:无论如何,许多事件都会从孩子传给父母。

于 2012-04-10T23:33:33.107 回答
0

我最终将 this.Click 替换为 base.Click。

    public new event EventHandler Click {
        add {
            base.Click += value;
            foreach (Control i in Controls) {
                i.Click += value;
            }
        }
        remove {
            base.Click -= value;
            foreach (Control i in Controls) {
                i.Click -= value;
            }
        }
    }
于 2012-04-11T00:16:53.717 回答
0

我想你想要这样的东西(不确定它是否适合私人成员):

private EventHandler mouseEnter;
public new event EventHandler MouseEnter {
add
{
    this.mouseEnter += value;
    foreach (Control i in Controls)
    {
        i.mouseEnter += value;
    }
}
remove
{
    this.mouseEnter -= value;
    foreach (Control i in Controls)
    {
        i.mouseEnter -= value;
    }
}

}

this.MouseEnter在递归中调用自己。

于 2012-04-10T23:35:51.770 回答