Thursday, March 31, 2011

Handle events for dynamic (run-time) controls - VB.NET

I have a WebBrowser control that is created and added to the form during run-time.

How do I connect this control to subroutine that can handle its events at run-time?

From stackoverflow
  • Use AddHandler

    e.g.

    AddHandler Obj.Ev_Event, AddressOf EventHandler
    

    and when you want to get rid of it (and you should get rid of it when you're done using it)

    RemoveHandler Obj.Ev_Event, AddressOf EventHandler
    

    in your case, you might have something like

    Dim web as New WebBrowser()
    AddHandler web.DocumentCompleted, AddressOf HandleDocumentCompleted
    

    assuming you'd created an event handler called HandleDocumentCompleted

    Depending on your needs, you could also use the WithEvents keyword when you declare your webbrowser; see the documentation.

  • I learned about this from examining the Form Designer generated code. Copy one of the examples from there, and if you look around you might learn some other valuable things about setting up controls at run-time.

    In C# its done with +=, on an event member of a class with a function as the parameter, but I do not have VB.net handy to check myself... sorry.

    EDIT: It's AddHandler as described well by Daniel L in his answer, and in full detail at msdn.

    • You will need to use AddHandler and RemoveHandler.
    • If you manually add an event through AddHandler be sure to remove it (in an appropriate location) using RemoveHandler.
    • Typing "AddHandler NameOfControl." will give a list of available events via intellisense.
    • Intellisense, documentation, (or the "error list"), will also give you the "signature" of the event handler.
    
    Private Sub WebBrowser1_Navigate(ByVal sender As Object, ByVal e As WebBrowserNavigatedEventArgs)
    
    End Sub
    
    Private Sub Form1_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
        RemoveHandler WebBrowser1.Navigated, AddressOf WebBrowser1_Navigate
    End Sub
    
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        AddHandler WebBrowser1.Navigated, AddressOf WebBrowser1_Navigate        
    End Sub
    
  • An alternative to using AddHandler is the declarative events syntax in VB. To use it, you declare the control (as a private member), using the WithEvents keyword. Then, the Handles keyword can be used on methods to handle the appropriate events:

    Private WithEvents m_WebBrowser As WebBrowser
    
    Private Sub WebBrowser_Navigate(ByVal sender As Object, ByVal e As WebBrowserNavigatedEventArgs) Handles m_WebBrowser.Navigate
        MsgBox("Hi there")
    End Sub
    
    Private Sub SomeActionThatCreatesTheControl()
        m_WebBrowser = New WebBrowser()
    End Sub
    

    There are mainly two advantages to this method:

    • No need for RemoveHandler,
    • No need to wire all event handlers manually: this is done automatically.
  • Example

    AddHandler SharedTimer.Tick, AddressOf SharedTimer_Tick

  • i've a few textboxes that needs to be added over a panel dynamically as per the number of rows in a dataset. Now the problem is that when i add an event handler to the dynamilcally added textboxes the event fired up for the textbox added at the last, none of the textbox is able to fire the event.

  • 'I have a method that discovers controls and adds handlers in certain situations.
    'Here is a simplified example.
    'Is it possible to pass in the handler at run time?

    Private Sub Example(byval ph as Placeholder)
      for each ctrl as control in ph.controls
        if typeof (ctrl) is textbox then
          dim cb as checkbox = ctrl
          AddHandler cb.DataBinding, AddressOf MyHandler
        end if
      next
    end sub
    

    'I'm looking to do something more like this...

    Private Sub Example(byval ph as Placeholder, **byref method as delagate**)
      for each ctrl as control in ph.controls
        if typeof (ctrl) is textbox then
          dim cb as checkbox = ctrl
          AddHandler cb.DataBinding, **method**
        end if
      next
    end sub
    

    The problem I'm having is in calling the method. This does not work:

    Example(myPlaceholder, addressof MyRuntimeHandler)
    

0 comments:

Post a Comment