Jump to content

Check out our Community Blogs

Register and join over 40,000 other developers!

Recent Status Updates

View All Updates

- - - - -

Creating controls at runtime

vb.net dynamic control creation event handlers sender object

  • Please log in to reply
No replies to this topic

#1 zeroGiven


    CC Resident

  • Advanced Member
  • PipPipPipPip
  • 61 posts
  • Programming Language:Visual Basic .NET
  • Learning:C#, Visual Basic .NET

Posted 03 March 2013 - 12:32 PM

This tutorial is intended to show how to create buttons without the use of the IDE drag and drop gui. There are times when you need a more dynamic set of controls which means you will need to know how to add them to the form and handle their events.


This tutorial is a little bit different than most because I wanted to make it easy for you to past into a project and test without creating a setup for of controls.


Instead of adding code snippets with explanations, I've opted to paste an entire tutorial/application that you can copy and paste into a blank project and see the results.


The comments in the code explain each line and why they are needed.



Public Class Form1
    'In writing this tutorial, I am going to create the entire layout of the form in code
    'You should be able to open a new blank windows form project and overwrite the
    'form code with this code and run.

    'There are times when you need to create controls on the fly.
    'The purpose of this tutorial is to show not only a basic creation
    'but to give the newly created items an event to handle.
    'We'll start off first by adding a panel to our form so that we can fill it
    'with a scrollable list of buttons.

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        'Set the form's width and height to a useable size
        Me.Width = 640
        Me.Height = 480

        'Let's put a panel on the form so that we can add some buttons to it
        Dim pnl As New Panel 'Instantiate a new panel object
        'any time we create a new control, we need to give it a location otherwise
        'your object won't know where it needs to be placed on the form
        pnl.Location = New Point(10, 10)
        'Just like with dragging controls onto the form, we can adjust the various
        'properties that it has.
        'Here we are sizing the panel to the width and height we prefer.
        pnl.Width = 200
        pnl.Height = 200
        'Since the default panel won't be seen on the form, let's give it a border so
        'that we know the control exists. We'll also change its background color to
        'make it stand out even more.
        pnl.BorderStyle = BorderStyle.FixedSingle
        pnl.BackColor = Color.DarkGray
        'Since I'm going to be adding more controls than can be displayed in this
        'panels dimensions, I am turning on the AutoScroll feature so that scrollbars
        'appear if needed
        pnl.AutoScroll = True

        'OK, at this point, we have everything we need for this particular object
        'If you were to stop here and run the form, you would receive a blank form.
        'That is because we have not yet added the control to the actual form.

        'We are now ready to add it to the form. When you add controls by dragging
        'you are adding them to the forms control collection. So that is what we
        'will have to do here.
        Me.Controls.Add(pnl) 'Using the controls collections .Add method we pass it the
        'object we instantiated earlier. In this case pnl.

        'So now, if you run the form, you will see the panel. But that's it, clicking
        'it will do nothing. It's just an empty container waiting for something to be
        'put into it.

        'So let's do just that. I'm going to automate this with a few simple calculations
        'to illustrate how simple it can be to speed up the process.
        'Let's create a loop that runs 10 times
        For x As Integer = 0 To 9 'I'll explain why I started at 0 further down.
            'With each iteration of the loop
            'Instantiate a new button object
            Dim btn As New Button
            'Just like with the panel, we need to set some of the button properties
            'I'm calling it Button# and I derive the number from the x iterator of the loop + 1
            'This will make the first button created Button1 (because 0+1 = 1)
            btn.Text = "Button" & x + 1
            'Width and height of the button
            btn.Width = 150
            btn.Height = 30
            'Again, we must have a location and this is why I started at 0
            'With each iteration of the loop, my Location.X remains the same
            'but I want to move the next button below the first so I multiply
            'x*33 (33 being just a little larger than the button so they don't overlap.
            'In the first iteration of the loop location.Y = 0*33 or 0 so Location.Y = 0
            'If I would have started the loop at 1 I would have created the button at the
            'y location of 33 leaving a blank at the top of the panel.
            btn.Location = New Point(3, 33 * x)
            'This is nothing more than ensuring the buttons use the Visual Style
            'you could just as easily used btn.BackColor = Color.Blue to have blue buttons.
            btn.UseVisualStyleBackColor = True
            'Once again, nothing will be added until you add the newly instantiated button to
            'the containers control collection.
            'Notice this is a little different than before because instead of putting the control
            'directly onto the form, we want to add it to our newly created panel's control collection.
            'OK, without this next line, you would generate a panel filled with 10 buttons but
            'clicking on those buttons would result in nothing happening. They would click but
            'what code would they run from the click? Well, we have to add a handler to make that
            'happen. If you drag a button on the form and double-click it, you may have noticed a
            'subroutine is created and at the far right of the sub line, is a Handles clause.
            'ie, Handles ButtonName.Click. We're going to do that in code now.

            'The following line adds a Click handler to the btn object and execute the sub btnClick
            'So everytime a button is clicked, the btnClick routine is executed.
            AddHandler btn.Click, AddressOf btnClick
        'You have just successfully created 11 objects on the fly (1 panel and 10 buttons) and
        'you've added the same routine for the 10 buttons. But if you were to stop here, you would
        'receive a squiggly error under the word btnClick. That's because we have to create the
        'subroutine for btnClick
    End Sub

    'Here we are adding the routine. But wait, if all the buttons use this same routine, how do we make them do
    'different things? Well, in a loop like this, we are typically making a group of functionally similar buttons
    'For something dramatically different, you would add a specific click handler for it. But to show how we
    'can differentiate these buttons in this example we are going to use the sender object.

    'If you create a button in the IDE, and double-click it, you may have noticed two arguments in the routine,
    'sender as Object and e as EventArgs. We're going to focus on sender for this example.
    'So, the sender is nothing more than the object that called the routine. But, it's just a generic object
    'the routine in this case doesn't specifically know its a button.

    Private Sub btnClick(sender As Object, e As EventArgs)
        'As I said above, sender is a generic object.  If we were to try to do something like
        'sender.UseVisualStyleBackColor = True we would see that it's not appearing in intellisense and that
        'it would generate an error. That's because UseVisualStyleBackColor is specific to a button but not
        'just any generic object. So we need to cast senders type to a button. We can do this easily
        'because we know only a button is calling this routine.

        'Let's make the sender a button
        Dim sentButton As Button = CType(sender, Button)
        'Now we can access the properties of the button control
        'Let's display a messagebox that shows the text of the button by using our newly cast sender
        'Notice above that when we casted it, we put it in a button object named sentButton.
        MessageBox.Show(sentButton.Text, "Button Information", MessageBoxButtons.OK, MessageBoxIcon.Information)
    End Sub
    'OK, this should be a good start to learning how to create controls with their various events.

    'In Closing, I will explain a little bit of how I used this method for a Timeclock application so that
    'you can see the versatility of it.

    'My timeclock form has a panel that when run, lists a button for each employee in the database.
    'Since I may hire or fire employees, I need to dynamically fill this list so that I don't need
    'to re-compile with a new button or removed button.
    'During creation, I set the text to the employee's name from the row result and insert the EmployeeID
    'into the button's .Tag property. When clicked, I have the id of the employee so that I can determine
    'what employeeid to store the TimeClockEntries table of my database.

    'If you have any questions, please feel free to comment and I'll try to help in any way I can.
End Class

Edited by Roger, 04 March 2013 - 09:08 AM.

  • 0

Also tagged with one or more of these keywords: vb.net, dynamic, control, creation, event handlers, sender object

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download