Journey
Journey

Reputation: 11

Creating a dynamic control array in VB.NET

Regarding a post I found here about VB6 control arrays pseudo-duplicated in .NET ... here's the link to that posting.

How to create Control Arrays in VB .NET

I am in need (or at least I'm thinking I'm needing) of a control array using labels. I started working on a form using panels to contain 49 labels each. After I finished the 1st panel, I copied and pasted it to make another then another and so on. On the first panel I named each label with a simple unique name Num1 for label1 Num2 for 2nd label and so on to Num49. I need each panels labels to have all the same names which of course can't work. All the copies I made enumerated the labels using default Label names. So I need a label control array to be able to change the labels forecolors and backcolors properties for each panel according to the text value in each label. Example: I will search a database for records where say column1 contains the value "1" then I want to change each label Num1 in each panel and reset the fore and back colors to highlight them from they rest of the number labels.(1 thru 49) No here's the kicker ... I need the array to be dynamic. I won't know how many panels will be needed until after the sql search on the Dbase is finished. Once I get the number of records for all hits for "1" in column1 I will need to Dim or ReDim the label array to accommodate the number of returned records. So for example say 20 records came back with "1" in column1, I would display 20 panels with the number "1" label in each panel highlighted from the rest of the number labels. Each labels text value is just the numbers from 1-49. This is just a simple example as I may be using more than one column in the search and highlighting more than just one number label. So I'm thinking this may not be possible. The answer given in the original posting I linked to above by Hans Passant was the one that caught my eye as being simple and easy to implement however I need it to be dynamic in that depending on how many records come back will determine how many panels will be needed and hence the size of the control array. I don't think I will be needing any event handling so that might make it much easier but there is the possibility that I might decide to have the user be able to click on a number label which would change the data to be displayed. ie. highlighting new labels with a refined search or a subset of the 1st search.

Any ideas ...can it be done ?

Here's the code snippet in Hans answer to create a control array of textboxes, the one without event handling. I liked this one cuz it was simple as easy.

Public Class Form1 Private OrderNumbers() As TextBox

Public Sub New()
    InitializeComponent()
    OrderNumbers = New TextBox() {TextBox1, TextBox2}
End Sub

End Class

Now can this be made to create x number of textboxes depending on how many records come back in my search. The items in the braces would have to be variables of some sort dependent on the number of array elements required ?

Upvotes: 0

Views: 2811

Answers (1)

B.McCorkle
B.McCorkle

Reputation: 13

Journey, I've been slowly moving from VB6 to VB.NET and working on similar issues with having to build arrays for use in loops. If the panels will be the same in appearance, you might try building one panel with the 49 labels with appropriate names so you can see what it will look like, then when you get the result of your search, dynamically add (or remove existing if doing a second search) panels with labels using the first panel as a template for spacing. Then use panel Name and Label Name Substring to help identify the controls. Or if you know the upper limit for how many panels you will need, you can build them all and use the panel Visible property to show or hide them as needed.

Suggestions for "appropriate names", use the "index number" as part of the name, using 0's for padding to get the same length for each name: Panels: pnl001, pnl002 ...

Labels: first 4 characters "lblN", next 3=Panel Number, last 2=Label Number, remember to NOT name other non-panel labels starting with "lblN"

in pnl001: lblN00101, lblN00102,...,lblN00149

in pnl002: lblN00201, lblN00202,...,lblN00249

Use Substring to get the "index". Panel number for a label would be Val(vCtrl.Name.Substring(3, 3))

If you decide to handle more complex results, if you store the panels in an array, vPnl(), you could make a subroutine to loop thru the panels with a For/Next, then loop thru the panel's controls and match the label names or their "index" last 2 characters with the search results.

If you decide to make the labels "clickable", if you are dynamically adding the controls, at the same time you can add the Event Handler. If the panels are built in design mode then the handler can be added using a loop in Form_Load so you don't have to remember to add the handler if you add more panels.

AddHandler vCtrl(vF).DoubleClick, AddressOf lblN_DoubleClick

Here's a link to adding controls dynamically How to programmatically add controls to a form in VB.NET

To loop through the labels in the panels:

    Dim vPnl() As Panel ' get the count on records result, then load array

    'pass the search result count and value to test for to a subroutine
    Private Sub proResult(ByVal pResultCt as Integer,ByVal pTest as Integer)
     pResultCt=pResultCt+1
 ' arrays are zero based, add 1 so your loops can be For x=1 to pResultCt
     ReDim vPnl(pResultCt)

     'store the first panel using 1 as index
     vPnl(1)=pnl001
     'dynamically create the number of panels needed
     'store each Panel in vPnl() as you add them
     . . .
     ' or show them and hide the rest if the panels are already built
     '  if doing this way then store the Panels in vPnl() array in Form_Load
     '  and do not use the ReDim above, loop thru the form controls, count
     '  the panels, redim vPnl() using the count+1 so it does not have to be 0 based,
     ' loop thru the form controls again looking
     '  for panel names and use vPnl(VAL(vCtl.Name.Substring(3,3)))=vCtl

     'loop through the panels
     For vF=1 to pResultCt 
      'loop through the controls in the panel, looking for labels
      ' start names with distinct pattern like "lblN"
      ' for the 1-49 label names, like "lblN00101","lblN00102"
      For Each vCtrl As Control In vPnl(vF).Controls
       If vCtrl.Name Like "lblN*" Then
        'get the label "index", VB6 would be VAL(RIGHT(vCtrl.Name,2))
        ' be careful with Substring, the startIndex parameter is 0 based LEFT(vCtrl.Name,2)
        '  would be vCtrl.Name.Substring(0,2)

        vK = Val(vCtrl.Name.Substring(Len(vCtrl.Name) - 2, 2))

        ' now you have the "index" of this label, panel vF, label vK
        ' you could do an If/Then based on it
        If vK=pTest then
         vCtrl.BackColor=Color.Yellow
        Else
         vCtrl.BackColor=Color.White
        End If
        ' or store it in an array variable for future use
      Next
     Next
    End Sub

Upvotes: 0

Related Questions