A group blog from members of the VB team
What’s wrong with the following WPF code?
Sub OK_Click(sender As Object, e As RoutedEventArgs) Handles OK.Click
Title="Window1" Height="300" Width="300">
<Button Name="OK" Click="OK_Click">OK</Button>
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
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.
My project for a few lines of code could ultimately be found here