为什么我的事件属性代码会导致堆栈溢出异常?

时间:2012-04-10 23:29:54

标签: c# winforms events properties user-controls

我正在制作一个自定义按钮(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;
        }
    }
}

3 个答案:

答案 0 :(得分:5)

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

查看您的代码,您似乎自己定义了加法器,以便不仅从控件添加和删除处理程序,还从其所有子项添加和删除处理程序。这让我感到非常糟糕:给定事件的订阅者有合理的期望,他们只会在实际事件被触发时被通知,而不是每当事件被任何数量的发布者解雇时他们什么都不知道。< / p>

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

最后,这个功能可能是不必要的:无论如何,很多事件会从孩子们冒充到父母身上。

答案 1 :(得分: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在递归中调用自己。

答案 2 :(得分:0)

我最终更换了这个。点击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;
            }
        }
    }