Events for runtime created controls.

T

Tym

I have a piece of code thus:

For iLOOP = 0 To iNoDays - 1
For jLOOP = 0 To iMaxPeriods - 1
iX = 10 + (iLOOP * (dCellWidth + 10))
iY = 10 + (jLOOP * (dCellHeight + 10)) +
Me.Size.Height / 4
If jLOOP = 0 And iLOOP = 0 Then
lblDISPLAY(((iLOOP) * iMaxPeriods) + jLOOP) = New
TextBox
lblDISPLAY(((iLOOP) * iMaxPeriods) + jLOOP).Text =
" "
lblDISPLAY(((iLOOP) * iMaxPeriods) +
jLOOP).Location = New Point(iX, iY)
lblDISPLAY(((iLOOP) * iMaxPeriods) +
jLOOP).AutoSize = False
lblDISPLAY(((iLOOP) * iMaxPeriods) + jLOOP).Height
= dCellHeight
lblDISPLAY(((iLOOP) * iMaxPeriods) + jLOOP).Width
= dCellWidth
lblDISPLAY(((iLOOP) * iMaxPeriods) +
jLOOP).Visible = False
lblDISPLAY(((iLOOP) * iMaxPeriods) + jLOOP).Name =
"txtPERIOD" & ((iLOOP) * iMaxPeriods) + jLOOP.ToString
Me.Controls.Add(lblDISPLAY(((iLOOP) * iMaxPeriods)
+ jLOOP))
Else
If jLOOP = 0 And iLOOP > 0 Then
lblDISPLAY(((iLOOP) * iMaxPeriods) + jLOOP) =
New TextBox
lblDISPLAY(((iLOOP) * iMaxPeriods) +
jLOOP).Text = WeekdayName(iLOOP, , FirstDayOfWeek.Sunday)
lblDISPLAY(((iLOOP) * iMaxPeriods) +
jLOOP).Location = New Point(iX, iY)
lblDISPLAY(((iLOOP) * iMaxPeriods) +
jLOOP).Height = dCellHeight
lblDISPLAY(((iLOOP) * iMaxPeriods) +
jLOOP).Width = dCellWidth
lblDISPLAY(((iLOOP) * iMaxPeriods) +
jLOOP).AutoSize = False
lblDISPLAY(((iLOOP) * iMaxPeriods) +
jLOOP).BorderStyle = BorderStyle.None
lblDISPLAY(((iLOOP) * iMaxPeriods) +
jLOOP).TextAlign = HorizontalAlignment.Center
lblDISPLAY(((iLOOP) * iMaxPeriods) +
jLOOP).Name = "txtPERIOD" & ((iLOOP) * iMaxPeriods) + jLOOP.ToString
Me.Controls.Add(lblDISPLAY(((iLOOP) *
iMaxPeriods) + jLOOP))
Else
If iLOOP = 0 And jLOOP > 0 Then
lblDISPLAY(((iLOOP) * iMaxPeriods) +
jLOOP) = New TextBox
lblDISPLAY(((iLOOP) * iMaxPeriods) +
jLOOP).Text = "Period " & jLOOP.ToString
lblDISPLAY(((iLOOP) * iMaxPeriods) +
jLOOP).Location = New Point(iX, iY)
lblDISPLAY(((iLOOP) * iMaxPeriods) +
jLOOP).Height = dCellHeight
lblDISPLAY(((iLOOP) * iMaxPeriods) +
jLOOP).Width = dCellWidth
lblDISPLAY(((iLOOP) * iMaxPeriods) +
jLOOP).AutoSize = False
lblDISPLAY(((iLOOP) * iMaxPeriods) +
jLOOP).BorderStyle = BorderStyle.None
lblDISPLAY(((iLOOP) * iMaxPeriods) +
jLOOP).TextAlign = HorizontalAlignment.Right
lblDISPLAY(((iLOOP) * iMaxPeriods) +
jLOOP).Name = "txtPERIOD" & ((iLOOP) * iMaxPeriods) + jLOOP.ToString
Me.Controls.Add(lblDISPLAY(((iLOOP) *
iMaxPeriods) + jLOOP))
Else
lblDISPLAY(((iLOOP) * iMaxPeriods) +
jLOOP) = New TextBox
lblDISPLAY(((iLOOP) * iMaxPeriods) +
jLOOP).Text = "Label No " & ((iLOOP) * iMaxPeriods) + jLOOP.ToString
lblDISPLAY(((iLOOP) * iMaxPeriods) +
jLOOP).Location = New Point(iX, iY)
lblDISPLAY(((iLOOP) * iMaxPeriods) +
jLOOP).Height = dCellHeight
lblDISPLAY(((iLOOP) * iMaxPeriods) +
jLOOP).Width = dCellWidth
lblDISPLAY(((iLOOP) * iMaxPeriods) +
jLOOP).AutoSize = False
lblDISPLAY(((iLOOP) * iMaxPeriods) +
jLOOP).Name = "txtPERIOD" & ((iLOOP) * iMaxPeriods) + jLOOP.ToString
Me.Controls.Add(lblDISPLAY(((iLOOP) *
iMaxPeriods) + jLOOP))
End If
End If
End If
Next jLOOP
Next iLOOP

which creates a grid of text boxes on a form at runtime dependent on
the number of days and the number of periods - its a timetable sort of
thing.

How do I capture events for these controls?
such as
private sub lblDISPLAY(((iLOOP) * iMaxPeriods)_Mouseclick

or

private sub lblDISPLAY(((iLOOP) * iMaxPeriods)_gotfocus

??
 
J

Jay B. Harlow [MVP - Outlook]

Tym,
You can use AddHandler & RemoveHandler, something like:

Dim index As Integer = ((iLOOP) * iMaxPeriods) + jLOOP

AddHandler lblDISPLAY(index).Click, AddressOf labelDisplay_Click
AddHandler lblDISPLAY(index).GotFocus, AddressOf
labelDisplay_GotFocus

Private Sub labelDisplay_Click(ByVal sender As Object, ByVal e As
System.EventArgs)

End Sub

Private Sub labelDisplay_GotFocus(ByVal sender As Object, ByVal e As
System.EventArgs)

End Sub

Hope this helps
Jay
 
T

Tym

Jay - excellent code - worked right out of the box!!

Just one further request - is there a way to detect which one has been
clicked??

advTHANKSance

Private Sub labelDisplay_Click(ByVal sender As Object, ByVal e As System.EventArgs)

msgbox ("You have clicked on cell number " & labelDISPLAY.Name)
' you get the idea... :)
 
J

Jay B. Harlow [MVP - Outlook]

Tym,
The sender parameter will be the specific TextBox that sent the message.

If your handler only handles TextBox events (you only use AddHandler on
TextBox objects) you can use:
Dim labelDISPLAY As TextBox = DirectCast(sender, TextBox)
msgbox ("You have clicked on cell number " & labelDISPLAY.Name)
' you get the idea... :)

If you use AddHandler on different type of controls, then I would recommend
using either Control & limit the event to properties common to all Controls,
or use TypeOf...
Dim labelDISPLAY As Control = DirectCast(sender, Control)

-- or --
If TypeOf sender Is TextBox Then
Dim labelDISPLAY As TextBox = DirectCast(sender, TextBox)
...
ElseIf TypeOf sender Is ComboBox Then
Dim labelDISPLAY As ComboBox = DirectCast(sender, ComboBox)
...
End If

Hope this helps
Jay
 
T

Tym

Jay - Thanks - this is working fine so far...

Private Sub labelDisplay_Click(ByVal Sender As Object, ByVal e As
System.EventArgs)
Dim labelDISPLAY As TextBox = DirectCast(Sender, TextBox)
MsgBox("Just clicked on a box! " & labelDISPLAY.ToString)
End Sub


but this returns the text within the text box. Is there a way to
detect the .name of the text box clicked on, rather than returning its
contents?

Thanks - your help is brilliant.
 
J

Jay B. Harlow [MVP - Outlook]

Tym
Have you tried using the Name property of labelDISPLAY?
MsgBox("Just clicked on a box! " & labelDISPLAY.Name)

Hope this helps
Jay
 
T

Tym

but this returns the text within the text box. Is there a way to
detect the .name of the text box clicked on, rather than returning its
contents?

Thanks - your help is brilliant.

Jay - found it....

Private Sub labelDisplay_Click(ByVal Sender As Object, ByVal e As
System.EventArgs)
Dim labelDISPLAY As TextBox = DirectCast(Sender, TextBox)
MsgBox("Just clicked on a box! " & labelDISPLAY.Name.ToString)
End Sub


Just needed to experiment a little - thanks for your help!
 
J

Jay B. Harlow [MVP - Outlook]

Tym,
labelDISPLAY.Name returns a string, there is no real need to call ToString
on it.
MsgBox("Just clicked on a box! " & labelDISPLAY.Name)

Hope this helps
Jay
 
T

Tym

labelDISPLAY.Name returns a string, there is no real need to call ToString
on it.

Yes - thanks. I realised that afterwards!!

Ok, so now I've got an event handler, how easy is it to refer to these
textboxes within my code elsewhere?

Normally, I would code:

If txtTextBox.Text = "Some Text" then
'my procedure....
End If

But as the name of the control is determined at runtime, I can't see a
straightworward way of doing this.

Sorry to bother you again...
 
J

Jay B. Harlow [MVP - Outlook]

Tym,
I would make the original array lblDISPLAY from your original code a class
(Form) level variable. Then index into it to get a specific TextBox.

Looking at your original code, I would probably make the original array a
two dimensional array (days & periods).

Something like:

Private lblDISPLAY(,) As TextBox

Private Sub CreateTextBoxes(...)
...
ReDim lblDISPLAY(iNoDays -1, iMaxPeriods -1)
For iLOOP = 0 To iNoDays - 1
For jLOOP = 0 To iMaxPeriods - 1
...
If jLOOP = 0 And iLOOP = 0 Then
lblDISPLAY(iLOOP, jLOOP) = New TextBox
lblDISPLAY(iLOOP, jLOOP).Text = " "

...

Next jLOOP
Next iLOOP
...
End Sub

Also, rather then using iLOOP & jLOOP, I would probably call them dayIndex &
periodIndex, as IMHO it makes the code easier to read:

For dayIndex = 0 To iNoDays - 1
For periodIndex= 0 To iMaxPeriods - 1
...
lblDISPLAY(dayIndex, periodIndex) = New TextBox


Then elsewhere:

lblDISPLAY(1,2).Text = "New Value"

Unfortunately you cannot index a control collection by name, as name is just
another "Tag" property. You could use a For Each loop to loop for a control
with a specific name or you could maintain a HashTable that maps names to
TextBoxes:

Something like:

lblDISPLAY(iLOOP, jLOOP).Name = ...
Me.Controls.Add(lblDISPLAY(iLOOP,jLOOP))
hashDISPLAY.Add(lblDISPLAY(iLOOP, jLOOP).Name, lblDISPLAY(iLOOP, jLOOP))

Where hashDISPLAY is a class (Form) level System.Collections.HashTable
variable.

Hope this helps
Jay
 
T

Tym

Thanks Jay - it's worked a treat

If you're ever in the UK - remind me i owe you a beer!
 
T

Tym

Thanks Jay - it's worked a treat

If you're ever in the UK - remind me i owe you a beer!

You can make it two, if you can answer this one though...

I need to be able to set the locked property to true/false but keep
getting the message

'Locked' is not a member of 'windows.system.forms.textbox'

How can I access the .locked property?

I am declaring it as

Public txtDISPLAY(,) As TextBox

(Changed it from lblDISPLAY as it's now a textbox and not a lable!!)

advTHANKSance
 
T

Tym

What are you expecting the "Locked" property to do for you at runtime?

Ah!

I was expecting it to be the same as in VB6 - stop text input into the
text boxes until, say, the "edit" button is clicked.

in vb6 txtTEXT1.Locked = True, used to allow this, with
txtTEXT1.Locked = false enabling text entry

The problem with the .ReadOnly = True/False, is that is changes the
background colour of the text box, which I didn't really want to do,
but am using it for now.
 
J

Jay B. Harlow [MVP - Outlook]

Tym,
Have you tried setting ReadOnly to true, then setting the BackGround color
to the color you want?

In VS.NET 2003 I had to select a different color for BackGround the select
BackGround = System.Window, otherwise it worked.

Hope this helps
Jay
 
T

Tym

Tym,
Have you tried setting ReadOnly to true, then setting the BackGround color
to the color you want?

Looks like that may be the way to go.

Thinking about it though... having the background colour different for
edit/non edit makes it a little clearer I suppose... :)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top