It is easy to add a control when you are designing a form - you simply drag the control from the Toolbox onto the form. But what if, for example, you want to add a button for each runner in a horse race? You can’t do this at design time because you don’t know how many runners there will be. Because the controls in the Toolbox are objects derived from classes, they can be added by the program while it is running.
To display the list of runners returned by a getMarket call, a logical choice would be to use either a ListBox or a DataGridView control. As an alternative, this step will show how to add a set of buttons for the runners in a market. This is an interesting exercise.
First add a new form to your project. From the Project menu select Add New Item . Select Windows Form and name it MarketForm.vb, then click the Add button. The new form should now appear in the solution explorer.
The code for the form is this:
Code:
Public Class MarketForm
Const PosLeft = 25 'Position of buttons from left edge of form
Const PosTop = 25 'Position of buttons from top of form
Const PosBut = 30 'Button spacing
Const Bwidth = 150 'Button width
Private Buttons As Button() 'The array of buttons
Sub AddRunnerButtons(ByVal oMarketResp As BFUK.GetMarketResp)
Dim Tpos As Integer = PosTop 'Top position of first button
Dim m As Integer = oMarketResp.market.runners.Length - 1 'Number of runners - 1
ReDim Buttons(m)
For i = 0 To m 'For each runner
Buttons(i) = New Button 'Create a new button object in the array element
With Buttons(i) 'Set button properties as required
.Left = PosLeft 'Set left position
.Text = oMarketResp.market.runners(i).name 'Set the text
.Tag = oMarketResp.market.runners(i).selectionId 'Save the selectionId in the button's Tag property
.TextAlign = ContentAlignment.MiddleLeft 'Set the text alignment
.Top = Tpos 'Set top position
.Width = Bwidth 'Set button width
End With
Controls.Add(Buttons(i)) 'Display this button on the form
AddHandler Buttons(i).Click, AddressOf RunnerButton_Click 'Assign the event handler for this button's click event
Tpos += PosBut 'Top position of the next button
Next
End Sub
'The 'Click' event handler
Private Sub RunnerButton_Click(ByVal sender As Object, ByVal e As System.EventArgs)
Dim RunnerButton As Button = sender 'A reference to the button that was clicked
With RunnerButton
MsgBox(.Tag & " " & .Text) 'Show the data for the clicked button
End With
End Sub
End Class
The constants (PosLeft, PosTop, PosBut, Bwidth) define the physical position of the buttons on the form. You can change these as required. These values are in pixels.
The Buttons array will hold references to the buttons that we add.
Sub AddRunnerButtons is called with the response object from a getMarket call as a parameter. This contains the runner info.
For each runner we create a new Button object from the Button class (in the System.Windows.Forms namespace) and assign it to the next array element. We now set the properties of this button to what we want. We set the button’s .Text property to the runner’s name, and the selectionId is stored in the .Tag property. (The .Tag is a handy property that you can use for any purpose.)
A windows form is said the be a “container” object, meaning that it can contain controls. Container objects have a Controls property which is a Collection object. (A Collection is a kind of array). The statement: Controls.Add(Buttons(i)) causes this button to appear on the form.
The AddHandler statement links this button’s Click event to the event handler sub.
That takes care of this button. the variable Tpos is incremented so that the top of the next button is positioned below this button. The process repeats until buttons for all runners have been created.
The click event handler Sub RunnerButton_Click is executed whenever one of the buttons is clicked. The sender parameter contains a reference to the button that was clicked. Using this we can access the button’s properties, in particular .Tag which holds the selectionId. You can now take action such as setting up a bet or displaying the prices for this runner.
Elsewhere in your program it is easy to access to properties of the runner buttons using the Buttons array. The buttons are numbered 0, 1, 2 ... n-1 corresponding to the array elements. For example:
Buttons(2).BackColor = Color.LightBlue
changes the colour of the button for the 3rd runner.