C# MouseDown事件友好循环实现及StackOverflowException异常解决
问题修复方案
问题根源
- 栈溢出原因:你在MouseDown事件处理方法中调用
base.OnMouseDown(e),而WinForms中Control.OnMouseDown方法会触发MouseDown事件,这就形成了无限递归循环:触发事件→执行处理方法→调用base.OnMouseDown→再次触发事件→...反复执行直到栈内存耗尽,抛出System.StackOverflowException。 - 循环逻辑问题:代码中直接修改类字段
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
相关产品推荐
相关产品推荐

