none
Limits on items in lists RRS feed

  • Question

  • I have created a simple grid using a list of cells (code attached) but would like to extend the grid without having to specify each cell, particularly since only the x and y values change for each cell. 

    Public Class Frmmain
        Dim cells As New List(Of cell)
    
        Sub Dolayout()
            Pnlmaze.Top = 50
            Pnlmaze.Left = 50
            Pnlmaze.Width = 250
            Pnlmaze.Height = 250
    
            PBplayer.Size = New Size(50, 50)
            'positions player in first square of grid
            PBplayer.Location = New Point(0, 0)
            PBplayer.BorderStyle = BorderStyle.FixedSingle
            PBplayer.BackColor = Color.Red
        End Sub
    
    
    
    
    
        Private Sub Frmmain_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    
            Dim cell1, cell2, cell3, cell4, cell5, cell6 As New cell
            With cell1
                .x = 0
                .y = 0
                .width = 50
                .height = 50
                .bordercol = Pens.Black
            End With
            With cell2
                .x = 50
                .y = 0
                .width = 50
                .height = 50
                .bordercol = Pens.Black
            End With
            With cell3
                .x = 100
                .y = 0
                .width = 50
                .height = 50
                .bordercol = Pens.Black
            End With
            With cell4
                .x = 0
                .y = 50
                .width = 50
                .height = 50
                .bordercol = Pens.Black
            End With
            With cell5
                .x = 50
                .y = 50
                .width = 50
                .height = 50
                .bordercol = Pens.Black
            End With
            With cell6
                .x = 100
                .y = 50
                .width = 50
                .height = 50
                .bordercol = Pens.Black
            End With
    
            cells.AddRange({cell1, cell2, cell3, cell4, cell5, cell6})
            Dolayout()
    
        End Sub
    
    
    
        Private Sub Pnlmaze_Paint(sender As Object, e As PaintEventArgs) Handles Pnlmaze.Paint
    
            For Each c As cell In cells
                Dim r As New Rectangle(c.x, c.y, c.width, c.height)
                e.Graphics.DrawRectangle(c.bordercol, r)
            Next
    
        End Sub
    
        Public Class cell
            Property x As Integer
            Property y As Integer
            Property width As Integer
            Property height As Integer
            Property wall As Boolean
            Property bordercol As Pen
        End Class
    End Class
    

    What I would ideally like to do is the same as I have worked out how to do creating a grid with labels. (code also attached)?

    Public Class Frmmain
        Sub Dolayout()
            Pnlmaze.Top = 50
            Pnlmaze.Left = 50
            Pnlmaze.Width = 330
            Pnlmaze.Height = 330
    
            PBplayer.Size = New Size(30, 30)
            'positions player in first square of grid
            PBplayer.Location = New Point(0, 0)
            PBplayer.BorderStyle = BorderStyle.FixedSingle
            PBplayer.BackColor = Color.Red
        End Sub
        Private Sub Frmmain_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            Dolayout()
            Dim mazegrid(10, 10) As Label
            Dim I As Integer 'I is column
            Dim J As Integer 'j is row
            Dim cellw As Integer = Pnlmaze.Width / 11
            Dim cellh As Integer = Pnlmaze.Height / 11
            Dim Left As Integer = 0
            Dim Top As Integer = 0
    
            For J = 0 To 10
                For I = 0 To 10
                    mazegrid(I, J) = New Label
                    mazegrid(I, J).Width = cellw
                    mazegrid(I, J).Height = cellh
                    mazegrid(I, J).Top = Top
                    mazegrid(I, J).Left = Left
                    mazegrid(I, J).BorderStyle = BorderStyle.FixedSingle
                    mazegrid(I, J).BackColor = Color.White
                    mazegrid(I, J).ForeColor = Color.Yellow
    
                    Pnlmaze.Controls.Add(mazegrid(I, J))
                    'create one row at a  time
                    Left += cellw
    
    
                Next
                'new row
                Left = 0
                Top += cellh
            Next
    
        End Sub
    

    <g class="gr_ gr_397 gr-alert gr_gramm gr_inline_cards gr_run_anim Punctuation only-ins replaceWithoutSep" data-gr-id="397" id="397">Hopefully</g> this is not too confusing 


    Monday, November 27, 2017 2:44 PM

Answers

  • Hi

    Here is some highly modified code, trying to illustrate some of the processes involved in handling a group of items in an interactive sense.

    This example is a stand alone project, with a blank Form1.

    The code shows moving the 'player' to a 'cell' when cell has a mouse left click.

    Shows the mouse click on the player (changes its colour)

    Displays Current cell Name and current mouse click position (relative to 'pnlmaze')

    NOTE: be aware that the Cells List is ZERO based.

    This code may answer some of your queries.

    Also note that there are MANY ways to do this sort of thing.

    ' blank Form1
    Option Strict On
    Option Explicit On
    Public Class Form1
        Dim cells As New List(Of cell)
        Dim Label1, Label2 As New Label
        Dim WithEvents pnlmaze, PBplayer As New Panel
        Dim curcell As cell = Nothing
        Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            Dolayout()
        End Sub
        Sub Dolayout()
            Dim x As Integer = 4
            Dim y As Integer = 4
            Dim z As Integer = 1
            For a1 As Integer = 1 To 25 Step 5
                For a2 As Integer = 1 To 5
                    Dim c As New cell
                    With c
                        .Name = "Cell" & z.ToString
                        .Loc = New Point(x, y)
                        .rec = New Rectangle(x, y, 44, 44)
                        .bordercol = Color.Black
                    End With
                    cells.Add(c)
                    x += 50
                    If x > 210 Then
                        x = 4
                        y += 50
                    End If
                    z += 1
                Next
            Next
            With Label1
                .Name = "Label1"
                .Location = New Point(55, 25)
                .AutoSize = True
            End With
    
            With Label2
                .Name = "Label2"
                .Location = New Point(170, 25)
                .AutoSize = True
            End With
    
            pnlmaze.Location = New Point(50, 50)
            pnlmaze.Size = New Size(254, 254)
            pnlmaze.BorderStyle = BorderStyle.FixedSingle
            AddHandler pnlmaze.Paint, AddressOf pnlmaze_Paint
    
            With PBplayer
                PBplayer.Size = New Size(30, 30)
                'positions player in first square of grid
                PBplayer.Location = New Point(8, 8)
                PBplayer.BorderStyle = BorderStyle.FixedSingle
                PBplayer.BackColor = Color.Green
            End With
            pnlmaze.Controls.Add(PBplayer)
            Controls.AddRange({pnlmaze, Label1, Label2})
    
            ChangeBorderColor("Cell1", Color.Blue)
    
            curcell = cells(14)
            PBplayer.Location = New Point(curcell.Loc.X + 8, curcell.Loc.Y + 8)
            ChangeBorderColor(curcell.Name, Color.Blue)
    
            Label1.Text = curcell.Name
    
        End Sub
        Private Sub pnlmaze_Paint(sender As Object, e As PaintEventArgs)
            For Each c As cell In cells
                e.Graphics.DrawRectangle(New Pen(c.bordercol, 4), c.rec)
            Next
        End Sub
        Private Sub Main_MouseClick(sender As Object, e As MouseEventArgs) Handles pnlmaze.MouseClick
            Dim p As Point = PointToClient(MousePosition)
            Dim nc As cell = FindCurrentCell(New Point(p.X - 50, p.Y - 50))
            If Not nc Is Nothing Then
                curcell = nc
                PBplayer.Location = New Point(curcell.Loc.X + 8, curcell.Loc.Y + 8)
                ChangeBorderColor(curcell.Name, Color.Blue)
            End If
    
            Label2.Text = "Mouse Position " & (p.X - pnlmaze.Location.X).ToString & "  " & (p.Y - pnlmaze.Location.Y).ToString
        End Sub
        Private Sub PBplayer_MouseClick(sender As Object, e As MouseEventArgs) Handles PBplayer.MouseClick
            Select Case PBplayer.BackColor
                Case Color.Green
                    PBplayer.BackColor = Color.Yellow
                Case Else
                    PBplayer.BackColor = Color.Green
            End Select
        End Sub
        Sub ChangeBorderColor(s As String, col As Color)
            For Each c As cell In cells
                c.bordercol = Color.Black
                If c.Name = s Then
                    c.bordercol = col
                    Label1.Text = c.Name
                End If
            Next
            Pnlmaze.Invalidate()
        End Sub
        Function FindCurrentCell(p As Point) As cell
            For Each c As cell In cells
                If c.rec.Contains(p) Then
                    Return c
                End If
            Next
            Return Nothing
        End Function
        Public Class cell
            Property Name As String
            Property Loc As Point
            Property rec As Rectangle
            Property bordercol As Color
        End Class
    End Class


    Regards Les, Livingston, Scotland

    • Marked as answer by CrazyMum123 Tuesday, November 28, 2017 9:56 PM
    Tuesday, November 28, 2017 2:43 PM

All replies

  • Hi

    Here is one way to do it. How ever many Points you add to the list, then a Cell will be added to the list of Cells.

    Option Strict On
    Option Explicit On
    Public Class Form1
        Dim cells As New List(Of cell)
        Dim p As New List(Of Point)
        Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            p.AddRange({New Point(0, 0),
                       New Point(50, 0),
                       New Point(100, 0),
                       New Point(0, 50),
                       New Point(50, 50),
                       New Point(100, 50)})
    
            For Each pt As Point In p
                Dim c As New cell
                With c
                    .x = pt.X
                    .y = pt.Y
                    .width = 50
                    .height = 50
                    .bordercol = Pens.Black
                End With
                cells.Add(c)
            Next
        End Sub
        Public Class cell
            Property x As Integer
            Property y As Integer
            Property width As Integer
            Property height As Integer
            Property wall As Boolean
            Property bordercol As Pen
        End Class
    End Class


    Regards Les, Livingston, Scotland

    Monday, November 27, 2017 2:58 PM
  • What if I want each cell to have a unique id so I can call on it individually later to set specific properties like 'wall' ?

    Monday, November 27, 2017 11:25 PM
  • What if I want each cell to have a unique id so I can call on it individually later to set specific properties like 'wall' ?

    You don't use an ID to refer to cells for updating properties - you use a variable.  The simplest sort of variable to use is a list, so you can use an index into the list to select each cell.   Just add the cell to the list as you create it - the list items will retain their sequence and index (unless you remove cells, of course).

    Dim Cells As New List(of cell)
    
    Private Sub Frmmain_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    
            Dim thisCell As New cell
            Cells.Add(thisCell)
            With thisCell
                .x = <calculated from counter>
                .y = <calculated from counter>
                .width = 50
                .height = 50
                .bordercol = Pens.Black
            End With
    


    • Edited by Acamar Tuesday, November 28, 2017 1:05 AM fmt
    Tuesday, November 28, 2017 1:04 AM
  • I have 25 cells, which I want to arrange in 5 columns and 5 rows, but do not want to manually create 25 cells.

    I want to be able to say create 25 cells, in 5 rows of 5 cells each, and give each of them a parameter I can ID them by e.g. Cell1 = (0,0) = column 0, row 0

    Tuesday, November 28, 2017 12:14 PM
  • I have 25 cells, which I want to arrange in 5 columns and 5 rows, but do not want to manually create 25 cells.

    I want to be able to say create 25 cells, in 5 rows of 5 cells each, and give each of them a parameter I can ID them by e.g. Cell1 = (0,0) = column 0, row 0

    What I usually do is have my game board cells located by (col, row). Then I have a function that converts from the game board to my list indices. Your list of cell data goes from 0 to 24. Each cell has its game board id as col, row. So you can use the function to retrieve the cell location in cols,rows from the cell list that is serial ie 0 to 24. And then a function to go the other way from cell to list index. Here you have to search the list for cells with the col, row from the grid cell.

    Also I store the cell, row value as a point but instead of x,y it is col, row.

    Many other ways to deal with it.

    Tuesday, November 28, 2017 1:10 PM
  • can you give me an example please - I am fairly new to all this and learning as I go along. many thanks
    Tuesday, November 28, 2017 1:52 PM
  • can you give me an example please - I am fairly new to all this and learning as I go along. many thanks

    https://social.msdn.microsoft.com/Forums/vstudio/en-US/3401f9f4-bfab-4586-ad47-f80c8bf1f46d/move-a-picturebox-along-a-game-grid?forum=vbgeneral

    https://social.msdn.microsoft.com/Forums/vstudio/en-US/6e93dde1-bc18-4439-9ece-1bea3cb7490d/creating-a-2d-sidescroller-map-with-tiles-from-a-text-file?forum=vbgeneral

    PS Look over these examples that do what I mention more or less. See if you can follow. Should give you lots of ideas. If you are still stuck I will make a simple example.

    Tuesday, November 28, 2017 1:59 PM
  • Hi

    Here is some highly modified code, trying to illustrate some of the processes involved in handling a group of items in an interactive sense.

    This example is a stand alone project, with a blank Form1.

    The code shows moving the 'player' to a 'cell' when cell has a mouse left click.

    Shows the mouse click on the player (changes its colour)

    Displays Current cell Name and current mouse click position (relative to 'pnlmaze')

    NOTE: be aware that the Cells List is ZERO based.

    This code may answer some of your queries.

    Also note that there are MANY ways to do this sort of thing.

    ' blank Form1
    Option Strict On
    Option Explicit On
    Public Class Form1
        Dim cells As New List(Of cell)
        Dim Label1, Label2 As New Label
        Dim WithEvents pnlmaze, PBplayer As New Panel
        Dim curcell As cell = Nothing
        Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            Dolayout()
        End Sub
        Sub Dolayout()
            Dim x As Integer = 4
            Dim y As Integer = 4
            Dim z As Integer = 1
            For a1 As Integer = 1 To 25 Step 5
                For a2 As Integer = 1 To 5
                    Dim c As New cell
                    With c
                        .Name = "Cell" & z.ToString
                        .Loc = New Point(x, y)
                        .rec = New Rectangle(x, y, 44, 44)
                        .bordercol = Color.Black
                    End With
                    cells.Add(c)
                    x += 50
                    If x > 210 Then
                        x = 4
                        y += 50
                    End If
                    z += 1
                Next
            Next
            With Label1
                .Name = "Label1"
                .Location = New Point(55, 25)
                .AutoSize = True
            End With
    
            With Label2
                .Name = "Label2"
                .Location = New Point(170, 25)
                .AutoSize = True
            End With
    
            pnlmaze.Location = New Point(50, 50)
            pnlmaze.Size = New Size(254, 254)
            pnlmaze.BorderStyle = BorderStyle.FixedSingle
            AddHandler pnlmaze.Paint, AddressOf pnlmaze_Paint
    
            With PBplayer
                PBplayer.Size = New Size(30, 30)
                'positions player in first square of grid
                PBplayer.Location = New Point(8, 8)
                PBplayer.BorderStyle = BorderStyle.FixedSingle
                PBplayer.BackColor = Color.Green
            End With
            pnlmaze.Controls.Add(PBplayer)
            Controls.AddRange({pnlmaze, Label1, Label2})
    
            ChangeBorderColor("Cell1", Color.Blue)
    
            curcell = cells(14)
            PBplayer.Location = New Point(curcell.Loc.X + 8, curcell.Loc.Y + 8)
            ChangeBorderColor(curcell.Name, Color.Blue)
    
            Label1.Text = curcell.Name
    
        End Sub
        Private Sub pnlmaze_Paint(sender As Object, e As PaintEventArgs)
            For Each c As cell In cells
                e.Graphics.DrawRectangle(New Pen(c.bordercol, 4), c.rec)
            Next
        End Sub
        Private Sub Main_MouseClick(sender As Object, e As MouseEventArgs) Handles pnlmaze.MouseClick
            Dim p As Point = PointToClient(MousePosition)
            Dim nc As cell = FindCurrentCell(New Point(p.X - 50, p.Y - 50))
            If Not nc Is Nothing Then
                curcell = nc
                PBplayer.Location = New Point(curcell.Loc.X + 8, curcell.Loc.Y + 8)
                ChangeBorderColor(curcell.Name, Color.Blue)
            End If
    
            Label2.Text = "Mouse Position " & (p.X - pnlmaze.Location.X).ToString & "  " & (p.Y - pnlmaze.Location.Y).ToString
        End Sub
        Private Sub PBplayer_MouseClick(sender As Object, e As MouseEventArgs) Handles PBplayer.MouseClick
            Select Case PBplayer.BackColor
                Case Color.Green
                    PBplayer.BackColor = Color.Yellow
                Case Else
                    PBplayer.BackColor = Color.Green
            End Select
        End Sub
        Sub ChangeBorderColor(s As String, col As Color)
            For Each c As cell In cells
                c.bordercol = Color.Black
                If c.Name = s Then
                    c.bordercol = col
                    Label1.Text = c.Name
                End If
            Next
            Pnlmaze.Invalidate()
        End Sub
        Function FindCurrentCell(p As Point) As cell
            For Each c As cell In cells
                If c.rec.Contains(p) Then
                    Return c
                End If
            Next
            Return Nothing
        End Function
        Public Class cell
            Property Name As String
            Property Loc As Point
            Property rec As Rectangle
            Property bordercol As Color
        End Class
    End Class


    Regards Les, Livingston, Scotland

    • Marked as answer by CrazyMum123 Tuesday, November 28, 2017 9:56 PM
    Tuesday, November 28, 2017 2:43 PM
  • This will keep me quiet for a few days - lots to learn and play with here - thanks Les
    Tuesday, November 28, 2017 6:10 PM