0

I am writing a program to display images through multiple PictureBoxes, and have decided that a tableLayoutPanel is a good way to do this. I currently have a 50x50 grid. The aim is to fill every column and row with PictureBoxes.

I also need to be able to resize this grid in future, so dragging and dropping pictureboxes isn't something I am able to do.

I have had a look for anyone trying to do the same thing, and have come across this but it was in C# and I am not good enough to translate it across.

I have attempted to do this, but I don't know how to start adding pictureboxes during runtime, and I suspect I am barking up the wrong methodical tree.

Dim tableSquareCollection = tableLayoutPanel1.Controls.OfType(Of TableLayoutPanel)() 'get collection of how many squares are in the table - this doesn't work, I can't find what datatype an empty square is

For i = 0 To tableSquareCollection.Count - 1
   'Add picture boxes to each square - but I have no ideas at how to start this
Next

I understand this is a minimal attempt at my question, but I can't see any further of a way through to my aim.

Thank you.

Joe Moore
  • 2,031
  • 2
  • 8
  • 29

2 Answers2

1

The code you posted doesn't really make any sense. If you're aim is to add controls to the TableLayoutPanel, why would you be looping through the Controls collection, which is a list of the existing controls? Also, why would you be trying to get TableLayoutPanels in your TableLayoutPanel?

If your aim is to add a PictureBox to the TableLayoutPanel then that's what you do. You need to create a PictureBox first and then add it:

Dim pb As New PictureBox

tableLayoutPanel1.Controls.Add(pb)

The control will get added to the next available cell automatically. If you have 50 rows by 50 columns then you need a loop with 50x50 iterations:

For i = 1 To tableLayoutPanel1.RowCount * tableLayoutPanel1.ColumnCount
    Dim pb As New PictureBox

    tableLayoutPanel1.Controls.Add(pb)
Next

That said, 2500 PictureBoxes on a form is almost certainly too many. If you want to resize the form and have the TableLayoutPanel expand and contract with it then the effect will not be smooth.

jmcilhinney
  • 50,448
  • 5
  • 26
  • 46
  • So now I'm thinking that I need to find a way of creating an image (bitmap or png etc) of my board, as described. My overall project aim is to create [this clever piece of javascript](http://nifty.stanford.edu/2014/mccown-schelling-model-segregation/) in visual basic. I have the backend sorted, but the frontend display is more of an issue. Thank you for your help. – Joe Moore Aug 23 '21 at 15:05
  • 1
    @JoeMoore, I would suggest not using controls at all but rather drawing the whole thing using GDI+. The code should not be all that complex and the whole thing will be far lighter than using loads of controls. Probably just use a 2D array to store the data and then fill a rectangle with one of three colours based on the corresponding array element. – jmcilhinney Aug 23 '21 at 15:35
  • Thank you very much, after a dive into GDI+, I've finally got a way to output my array. – Joe Moore Aug 23 '21 at 16:09
  • 1
    @JoeMoore, you should still accept this answer if it did indeed answer your original question, even if you end up going a different way. It means that people will know that you don't need further help without opening and reading the whole thread and the answer may still help someone else with fewer controls. – jmcilhinney Aug 24 '21 at 00:25
  • I meant to but forgot, apologies – Joe Moore Aug 24 '21 at 18:34
0

I recommend you use a FlowLayoutPanel instead. This will handle resizing:

Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    FlowLayoutPanel1.Anchor = AnchorStyles.Top Or AnchorStyles.Left Or AnchorStyles.Bottom Or AnchorStyles.Right
    FlowLayoutPanel1.BorderStyle = BorderStyle.Fixed3D
    FlowLayoutPanel1.Controls.Add(New PictureBox With {.Image = GetBitmap(Brushes.Red)})
    FlowLayoutPanel1.Controls.Add(New PictureBox With {.Image = GetBitmap(Brushes.Black)})
    FlowLayoutPanel1.Controls.Add(New PictureBox With {.Image = GetBitmap(Brushes.Orange)})
    FlowLayoutPanel1.Controls.Add(New PictureBox With {.Image = GetBitmap(Brushes.Green)})
    FlowLayoutPanel1.Controls.Add(New PictureBox With {.Image = GetBitmap(Brushes.Blue)})
End Sub

Function GetBitmap(br As Brush) As Bitmap
    Dim b = New Bitmap(100, 100)
    Using g As Graphics = Graphics.FromImage(b)
        g.FillRectangle(br, New Rectangle(0, 0, 100, 100))
    End Using
    Return b
End Function
SSS
  • 4,807
  • 1
  • 23
  • 44
  • This would work if I was using alot fewer pictureboxes, thank you for your solution though. – Joe Moore Aug 24 '21 at 18:35
  • 1
    A `FlowLayoutPanel` would be appropriate for an image viewer or the like but that's not what this is. The question specifically mentions a 50x50 grid and, if you check the link provided in the comment under my answer, you can see the intended result and the fact that a `FlowLayoutPanel` is not appropriate because flow is not desired. – jmcilhinney Aug 25 '21 at 01:23