Jack Millard Jack Millard - 1 month ago 13
Vb.net Question

Problems with generating labels

The Problem: I'm programmatically generating labels but am having trouble referencing them in code because they don't exist at runtime.

The Context: For a game, I've generated a 10x10 grid of labels with the following:

Public lbl As Label()
Dim tilefont As New Font("Sans Serif", 8, FontStyle.Regular)

Private Sub Lucror_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim i As Integer = 0
Dim a As Integer = 0
Dim height As Integer
Dim width As Integer

height = 30
width = 30

ReDim lbl(99)
For i = 0 To 99
lbl(i) = New Label
lbl(i).Name = i
lbl(i).Size = New System.Drawing.Size(30, 30)
lbl(i).Location = New System.Drawing.Point((width), height)
lbl(i).Text = i
lbl(i).Font = tilefont
Me.Controls.Add(lbl(i))

width = width + 30
a = a + 1 'starting new line if required
If (a = 10) Then
height = height + 30
width = 30
a = 0
End If
Next
End Subenter code here


This worked fine but the labels function as tiles in the game and game tiles need to store 2-3 integers each as well as be able to be referenced through event handlers. I figured a possible way to store integers would be to generate 100 arrays, each named after a label and each holding the 2-3 integers, but that seems very redundant.

What I need:


  • On click and on hover event handlers for every label

  • An array (or dictionary?) to store 2-3 integers for every label

  • Labels have to reference each others names ie. do something to label with name (your name + 1).



The Question: Is there a simple way to achieve these three things with the current way I generate labels (and if so, how?) and if not, how else can I generate the 100 labels to make achieving these things possible?

Any help is much appreciated.

Answer

Your labels do exist at runtime, but not at compile time. Attaching events is a little different at runtime, you must use AddHandler.

Below is some sample code that should illustrate everything you're asking for. I've introduced inheritance as a way of saving data that is pertinent to each tile. The GameTile type behaves exactly as a label, and we've added some functionality for storing integers and naming the control.

Public Class Form1
  Dim tilefont As New Font("Sans Serif", 8, FontStyle.Regular)
  Public Property GameTiles As List(Of GameTile)

  Private Sub Lucror_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    Dim a As Integer = 0
    Dim xPosition As Integer = 30
    Dim yPosition As Integer = 30
    GameTiles = New List(Of GameTile)
    For i = 0 To 99
      Dim gt As New GameTile(i.ToString)
      gt.Size = New System.Drawing.Size(30, 30)
      gt.Location = New System.Drawing.Point((yPosition), xPosition)
      gt.Font = tilefont
      gt.Integer1 = i + 1000
      gt.Integer2 = i + 2000
      gt.Integer3 = i + 3000
      Me.Controls.Add(gt)
      AddHandler gt.Click, AddressOf TileClickHandler
      GameTiles.Add(gt)
      yPosition = yPosition + 30
      a = a + 1 'starting new line if required
      If (a = 10) Then
        xPosition = xPosition + 30
        yPosition = 30
        a = 0
      End If
    Next
  End Sub
  Private Sub TileClickHandler(sender As Object, e As EventArgs)
    Dim gt = CType(sender, GameTile)
    MsgBox("This tile was clicked: " & gt.Text &
            Environment.NewLine & gt.Integer1 &
            Environment.NewLine & gt.Integer2 &
            Environment.NewLine & gt.Integer3)
  End Sub
End Class

Public Class GameTile
  Inherits Label
  'this class should be in a separate file, but it's all together for the sake of clarity
  Public Property Integer1 As Integer
  Public Property Integer2 As Integer
  Public Property Integer3 As Integer

  Public Sub New(NameText As String)
    MyBase.New()
    Name = NameText
    Text = NameText
  End Sub
End Class