Why is my event handler firing two times?

1.1k views Asked by At

I have a bunch of panels that I am adding to a single parent panel and I want to add event listeners to all of the panels but not until after they have all been added to the parent (becuase I don't want the event listeners firing each time a new panel gets added). So I am using the following code:

   Dim temp_object As question_bar = Nothing
   For Each q As Object In review_holder.Controls
       If TypeOf q Is question_bar Then
          temp_object = q
          AddHandler temp_object.Resize, AddressOf temp_object.resize_me
       End If
   Next

   For Each q As Object In review_holder.Controls
      If TypeOf q Is question_bar Then
         temp_object = q
         temp_object.resize_me()
      End If
   Next

But I noticed that the resize_me() subroutine is getting fired twice for each control. I only want it to fire once. So I traced it out using this code

MsgBox((New System.Diagnostics.StackTrace).GetFrame(1).GetMethod.Name)

and I see that each time it gets called the calling methods are both this subroutine and _Lambda$_365. What the heck is that? How do I find out where that is coming from?

BTW, this is a winforms app using VS2012.

EDIT ------------------------------------------------------------------------

Public Sub resize_me()

 MsgBox((New System.Diagnostics.StackTrace).GetFrame(1).GetMethod.Name)

 If Me.minimized = True Then
    Me.Height = 0
    Exit Sub
 End If

 number_panel.Width = my_parent.number_width
 number_text.Width = my_parent.number_width
 number_separator.Left = number_panel.Right
 question_panel.Left = number_separator.Right
 question_panel.Width = question_panel.Parent.Width * initial_question_width + (question_padding * 2)


End Sub
1

There are 1 answers

1
Steve On

Well changing size properties when you are inside a resize event could explain why your code is recalled again a second time. Usually I try to avoid this kind of situations but this is not always possible. In these cases then a global variable that acts as a flag to block the reentry could save the day

Dim insideResize As Boolean

Public Sub resize_me()

 if insideResize = True Then
     Exit Sub
 End if

 insideResize = True
 Try
    If Me.minimized = True Then
       Me.Height = 0
       Exit Sub
    End If

    number_panel.Width = my_parent.number_width
    number_text.Width = my_parent.number_width
    number_separator.Left = number_panel.Right
    question_panel.Left = number_separator.Right
    question_panel.Width = question_panel.Parent.Width * initial_question_width + (question_padding * 2)
  Finally
    insideResize = False
  End Try

End Sub

To stay on the safe side with this patterns remember to always use a Try/Finally block to be sure that when you exit from the Resize event the global flag is correctly set back to false.