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上。
更优的控件重写方式
为了避免这类事件绑定的陷阱,推荐把事件订阅和业务逻辑分离:
- 父类中只定义虚方法,不在方法上直接用
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
- 子类只需重写虚方法即可,无需处理事件绑定:
' (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
相关产品推荐
相关产品推荐

