Spot the Bug! – Is it in VB or XAML? (Jonathan Aneja)

VBTeam

What’s wrong with the following WPF code?

 

Class Window1

 

  Sub OK_Click(sender As Object, e As RoutedEventArgs) Handles OK.Click

      MsgBox(“Button Clicked”)

  End Sub

 

End Class

 

<Window x:Class=”Window1″

    xmlns=”http://schemas.microsoft.com/winfx/2006/xaml/presentation”

    xmlns:x=”http://schemas.microsoft.com/winfx/2006/xaml”

    Title=”Window1″ Height=”300″ Width=”300″>

    <Grid>

        <Button Name=”OK” Click=”OK_Click”>OK</Button>

    </Grid>

</Window>

 

.

 

.

 

.

 

.

 

.

 

Answer: The message box will be displayed twice!  To understand why, open up the project in Reflector, and in the System_Windows_Mark_IComponentConnector_Connect method you’ll see these two lines:

    Me.OK = DirectCast(target, Button)
    AddHandler Me.OK.Click, New RoutedEventHandler(AddressOf Me.OK_Click)

 

Ok so we’re adding one handler here, but click the link to navigate to “OK”.  You’ll see this is actually a property of type Button (that’s what the compiler does for WithEvents/Handles – the full story of how WithEvents works is its own blog entry…).  In the Setter you’ll see this code:

 

    If (Not Me._OK Is Nothing) Then
        AddHandler Me._OK.Click, handler
    End If

 

So now we can clearly see there’s two AddHandler calls and thus the event gets handled multiple times by the same method (which is perfectly legal).  One of them came from Handles OKButton.Click, and the other came from Click=”OK_Click”. 

 

The key thing to realize is that if you wire up the eventhandler in XAML, don’t wire it up in code using Handles (and vice-versa).  Thankfully in this scenario it’s obvious that there’s a problem because there’s a message box, but if the eventhandler was doing something more subtle (such as incrementing a counter or modifying some other state), this can lead to hard-to-diagnose bugs.

0 comments

Leave a comment

Feedback usabilla icon