VV5198722 VV5198722 - 5 months ago 34
Vb.net Question

WithEvents bug in Visual Studio 2015?

I probably encountered an issue of Visual Studio 2015. If you define three handlers of the same event using

WithEvents
and
Handles
keywords, one of the handlers will not be called. I traced this behavior in our software and wrote following WinForms sample project.

Public Class MainBase1
Inherits Form

Protected WithEvents Button1 As Button
Protected TextBox1 As TextBox

Public Sub New()
SuspendLayout()

Text = "WithEvents Test"
ClientSize = New Size(300, 300)

Button1 = New Button()
Button1.Location = New Point(10, 10)
Button1.Size = New Size(100, 25)
Button1.Text = "Button1"
Controls.Add(Button1)

TextBox1 = New TextBox()
TextBox1.Location = New Point(10, 50)
TextBox1.Multiline = True
TextBox1.Size = New Size(280, 240)
Controls.Add(TextBox1)

ResumeLayout(False)
PerformLayout()
End Sub

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
TextBox1.Text &= "MainBase1: Button click handled." & vbNewLine
End Sub
End Class


Public Class MainBase2
Inherits MainBase1

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
TextBox1.Text &= "MainBase2: Button click handled." & vbNewLine
End Sub
End Class


Public Class Main
Inherits MainBase2

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
TextBox1.Text &= "Main: Button click handled." & vbNewLine
End Sub
End Class


After clicking
Button1
Textbox1
contains

MainBase1: Button click handled.
Main: Button click handled.


If I compile the same sample under Visual Studio 2012, I get

MainBase1: Button click handled.
MainBase2: Button click handled.
Main: Button click handled.


Has anybody encountered this issue as well? Or have I missed something?

Answer

This bug still remains. Here is my solution to this.

I made the handler in MainBase1 Protected Overridable. Subclasses don't use Handles but override the handler and call MyBase.

This approach has the advantage that execution order of handlers is well-defined.

Public Class MainBase1
    Inherits Form

    Protected WithEvents Button1 As Button
    Protected TextBox1 As TextBox

    Public Sub New()
        SuspendLayout()

        Text = "WithEvents Test"
        ClientSize = New Size(300, 300)

        Button1 = New Button()
        Button1.Location = New Point(10, 10)
        Button1.Size = New Size(100, 25)
        Button1.Text = "Button1"
        Controls.Add(Button1)

        TextBox1 = New TextBox()
        TextBox1.Location = New Point(10, 50)
        TextBox1.Multiline = True
        TextBox1.Size = New Size(280, 240)
        Controls.Add(TextBox1)

        ResumeLayout(False)
        PerformLayout()
    End Sub

    Protected Overridable Sub Button1_Click(sender As Object, e As EventArgs) _
    Handles Button1.Click
        TextBox1.Text &= "MainBase1: Button click handled." & vbNewLine
    End Sub
End Class


Public Class MainBase2
    Inherits MainBase1

    Protected Overrides Sub Button1_Click(sender As Object, e As EventArgs)
        MyBase.Button1_Click(sender, e)
        TextBox1.Text &= "MainBase2: Button click handled." & vbNewLine
    End Sub
End Class


Public Class Main
    Inherits MainBase2

    Protected Overrides Sub Button1_Click(sender As Object, e As EventArgs)
        MyBase.Button1_Click(sender, e)
        TextBox1.Text &= "Main: Button click handled." & vbNewLine
    End Sub
End Class