You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C# MouseDown事件友好循环实现及StackOverflowException异常解决

问题修复方案

问题根源

  1. 栈溢出原因:你在MouseDown事件处理方法中调用base.OnMouseDown(e),而WinForms中Control.OnMouseDown方法会触发MouseDown事件,这就形成了无限递归循环:触发事件→执行处理方法→调用base.OnMouseDown→再次触发事件→...反复执行直到栈内存耗尽,抛出System.StackOverflowException。
  2. 循环逻辑问题:代码中直接修改类字段alts_Y,每次触发事件都会累加该值,导致后续按钮区域的位置完全偏离预期;同时内层的x循环完全冗余(仅循环1次,无实际作用)。

修复步骤与代码

情况1:使用事件处理程序(你的原有代码写法)

直接移除base.OnMouseDown(e)的调用,同时修复循环中坐标计算的逻辑,避免修改原字段:

private void Dashboard_MouseDown(object sender, MouseEventArgs e)
{
    // 用临时变量计算当前按钮Y坐标,保留原alts_Y的值
    int currentY = alts_Y;
    for (int y = 0; y < alts; ++y)
    {
        Rectangle buttonRect = new Rectangle(735, currentY + 5, 45, 15);
        if (buttonRect.Contains(e.Location))
        {
            this.Invalidate();
            // 若只需处理第一个被点击的按钮,可添加break终止循环
            // break;
        }
        currentY += 72;
    }
}

情况2:重写OnMouseDown方法(更规范的WinForms自定义控件写法)

如果你的Dashboard是自定义控件,推荐重写基类的OnMouseDown方法,此时调用base.OnMouseDown(e)是安全的(不会触发递归):

protected override void OnMouseDown(MouseEventArgs e)
{
    // 先处理自定义点击判断逻辑
    int currentY = alts_Y;
    for (int y = 0; y < alts; ++y)
    {
        Rectangle buttonRect = new Rectangle(735, currentY + 5, 45, 15);
        if (buttonRect.Contains(e.Location))
        {
            this.Invalidate();
            break;
        }
        currentY += 72;
    }
    // 调用基类方法,确保事件正常触发
    base.OnMouseDown(e);
}

内容的提问来源于stack exchange,提问作者HHopter

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 18:37:35