Best way mass produce label control set

I have had the need to create many members of a control set of labels. (100). What I did was create a few and then duplicated them and then duplicated again until I got my 100.

I suspect that this technique caused me problems. Some of the members of the control set became “parents” of other members. I was naive enough not even to know what this meant until helped by others on the forum.

What is the best way to create a large set of label controls on a window. I would plan to move them into their proper location as a second step.

Honestly, I’d keep away from that where at all possible. If you have to, create them at runtime or consider where you can replace them entirely by drawing on a canvas or directly on the window at the appropriate coordinates. Your UI speed and sanity will thank you in the long run. If you have to do it, try encompassing multiple controls in a container, then you not only have the ability to alter all of your repeats at once in one location but you’ll cut down on the number of clickable objects on the window which will ultimately speed things up when designing the form.

2 Likes

Use EmbedWithin. The following code makes 31 containers for each day of the month:

dim OffSetX, OffSetY as Integer
for currentDay as Integer = 0 to (MaxWeeks * NoOfDaysPerWeek) - 1
  
  if currentDay mod NoOfDaysPerWeek = 0 then
    if currentDay > 0 then OffSetY = OffSetY + DayHeight
    OffSetX = 0
  end if
  
  dim theDay as new SingleDay
  theDay.EmbedWithin(self)
  theDay.Day = currentDay + 1
  theDay.Left = OffSetX
  theDay.top = OffSetY
  theDay.Width = DayWidth
  theDay.Height = DayHeight
  OffSetX = OffSetX + DayWidth
  theDay.registerObserver WeakAddressOf UpdateDay
  DayContainers.Add(theDay)
  if currentDay = 0 then theDay.IsSelected = True
Next

self.Refresh

All drawing is handled in the canvas that is in the SingleDay container:

Screenshot 2021-12-18 at 17.43.54

I’ll upload the project tomorrow.

1 Like

if you put 10 labels into a container control as template you have only 10 cc in the window.

1 Like

if you put 10 labels into a container control as template you have only 10 cc in the window.

But as I read this, a container control cannot be a member of a Set. So if I want to put 100 of these on a window, I have to have 100 individual container controls with no easy way to reference them or their contents.

In my current design, I have a set of 100 rectangles on which there are 4 labels. So I end up with 5 sets, each with 100 members in my window. Since all these 5 elements are indexed, they are easy to reference in code so I can change their values etc. And I can detect when they are clicked on and I get an index reference.

Trying to understand the comments quoted at the start of this note, I took it to mean that I could create a container control that might look like the below with a rectangle in the background and the labels on the top of the rectangle.

Screen Shot 2021-12-31 at 12.16.48 AM

But then I run across the statement that I cannot create a set of container controls.

So I would have to create 100 independent instances of the container control. Is this reasonable? How would I know which one was clicked on? How would I reference the labels on the various container controls to change, for example, the fourth one? It seems that I have created a mess. In the Navigator Panel, I would have a huge (100) list of container control instances to deal with. Would I be creating a property of the container control that was its “ID” say a string 00 or 01 or 02 or 03 and somehow making that work?

Basically is there a commonly used pattern to create a “pseudo” set of container control instances in the window that makes sense?

Please check the day of month picker I made. From the open event of the main container:

for currentDay as Integer = 0 to (MaxWeeks * NoOfDaysPerWeek) - 1
  
  if currentDay mod NoOfDaysPerWeek = 0 then
    if currentDay > 0 then OffSetY = OffSetY + DayHeight
    OffSetX = 0
  end if
  
  dim theDay as new SingleDayForMonth
  theDay.EmbedWithin(self)
  theDay.Day = currentDay + 1
  theDay.Left = OffSetX
  theDay.top = OffSetY
  theDay.Width = DayWidth
  theDay.Height = DayHeight
  OffSetX = OffSetX + DayWidth
  theDay.registerObserver WeakAddressOf UpdateDay
  DayContainers.Add(theDay)
  if currentDay = 0 then theDay.IsSelected = True
Next
1 Like

you can, just use an CC Event and add them to a Window property list/array with kind of this object or interface name. you can also give your cc a extra id property and set it in the designer window.

with this list you can iterate by for each.

1 Like

I reviewed Beatrix’s code and was able to adapt it to my use case. It worked brilliantly!

What I had done originally was to create a 10 by 10 grid of rectangles (set of 100) and place what ultimately was 5 labels on each rectangle (each a set of 100). This actually worked. To change the “look” of an individual cell was accomplished by changing the content of one or more of the labels in the cell - text value, color etc.

BUT

  1. It was very painful to set up which prompted my original question
  2. It made the IDE a bit less responsive (but actually tolerable)
  3. Changing anything was going to be very painful. Making the cells a little bigger puts you in a world of hurt.

Beatrix’s solution to a similar problem was to design a ContainerControl for a “cell” that contained a Canvas. One thing I learned (and Markus emphasized as well) is that it is possible to create an array of container controls as a property of a Window. This solves the “indexing problem”. You now have an index to reference any cell and make visual modifications as the UI requires. The positions of the “cells” are established in code which is vastly easier than setting up by hand 100 rectangles and 500 overlying labels.

All the visual changes to the grid members’ appearance are done in code in the Paint event of the Canvas that occupies the space of the individual cell. This is much more flexible, and actually fairly easy, having the Beatrix model on hand for guidance.

I was initially nervous looking at the Beatrix code because it contained fancy things like Delegates and WeakAddressOf which are over my head. But none of this was required for my purposes. I did not have to design a control to be used by other people. Beatrix puts Containers in a Container, but I needed only to put one Container type directly on the Window.

1 Like