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

VB.Net中继承窗体的重写控件事件被触发两次问题排查

问题原因

你的代码中重写的ButtonDoStuff_Click被调用两次,核心原因是事件重复绑定:

  • 父类的ButtonDoStuff_Click方法通过Handles ButtonDoStuff.Click已经完成了控件点击事件的绑定;
  • 子类重写该方法时,又添加了Handles ButtonDoStuff.Click,相当于给按钮的Click事件多订阅了一次处理逻辑,因此点击按钮时会执行两次重写后的方法。

至于父类的方法断点没触发,是因为VB.NET中重写方法默认不会自动调用父类的实现,除非你在子类方法中显式调用MyBase.ButtonDoStuff_Click(sender, e)。

解决方法

直接移除子类重写方法上的Handles ButtonDoStuff.Click即可,父类的绑定已经足够让重写方法被触发:

' (TestApp.vbproj)
Public Class FormNewMain
  Inherits ProjectBase.FormBaseMain

  Protected Overrides Sub ButtonDoStuff_Click(sender As Object, e As EventArgs)
    MsgBox("test")
    ' 如果需要执行父类的逻辑,添加下面这行
    ' MyBase.ButtonDoStuff_Click(sender, e)
  End Sub

End Class

另外你在FormNewMain_Load里的RemoveHandler完全没必要,因为父类的事件绑定是在窗体初始化阶段完成的,子类加载时移除的操作无法覆盖父类的绑定逻辑,且本身重复绑定的问题根源在子类的Handles上。

更优的控件重写方式

为了避免这类事件绑定的陷阱,推荐把事件订阅和业务逻辑分离:

  1. 父类中只定义虚方法,不在方法上直接用Handles,而是手动在父类的构造函数或Load事件中绑定控件事件:
' (ProjectBase.vbproj)
Public Class FormBaseMain
  Public Sub New()
    InitializeComponent()
    ' 手动绑定事件到虚方法
    AddHandler ButtonDoStuff.Click, AddressOf ButtonDoStuff_Click
  End Sub

  Protected Overridable Sub ButtonDoStuff_Click(sender As Object, e As EventArgs)
    ' 父类默认逻辑
  End Sub
End Class
  1. 子类只需重写虚方法即可,无需处理事件绑定:
' (TestApp.vbproj)
Public Class FormNewMain
  Inherits ProjectBase.FormBaseMain

  Protected Overrides Sub ButtonDoStuff_Click(sender As Object, e As EventArgs)
    ' 子类自定义逻辑
    MsgBox("test")
    ' 可选:调用父类逻辑
    ' MyBase.ButtonDoStuff_Click(sender, e)
  End Sub
End Class

这种方式更清晰,避免了VB.NETHandles关键字在继承场景下的隐式绑定问题,也让逻辑分工更明确。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 12:23:26