Can you link an array variable with a control? - arrays

I am making a program with PictureBox controls. It would be easiest to manage the things I want to do with the PictureBox controls if they were in an array already.
This is what I have tried.
Sub drawtiles()
For x As Integer = 0 To 32 Step 1
For y As Integer = 0 To 24 Step 1
Dim tile As New PictureBox()
tile.Width = 20
tile.Height = 20
tile.Top = y * 20
tile.Left = x * 20
tile.BackColor = Color.CornflowerBlue
Dim r As Random = New Random
' Get random numbers between 1 and 3.
' ... The values 1 and 2 are possible.
Dim s As Integer = (r.Next(1, 3))
If s = 1 Then
tile.BackgroundImage = My.Resources.g1774
Else
tile.BackgroundImage = My.Resources.rect881
End If
tiles(x)(y) = tile
Controls.Add(tile)
Next
Next
End Sub
... with the array being made here
Public Class Form1
Public tiles As Array
So, how would I assign the Picturebox control, to the 3d array value?

You should almost never declare something as type Array. That is really only for when you want to be able to refer to an array of any type. That usually only happens with method parameters but, since the advent of generics, you can just write a generic method where the generic type parameter is the type of the array, e.g.
Private Sub ProcessArray(Of T)(array As T())
For i = 0 To array.GetUpperBound(0)
'Process element at index i here.
Next
End Sub
If you want an array of PictureBoxes then create a PictureBox array. Also, don't use a jagged array when you should be using a 2D array. This is a jagged array of PictureBoxes:
Private jaggedArrays As PictureBox()()
and this is a 2D array:
Private twoDimensionalArray As PictureBox(,)
The difference is that the second is a single object whereas the first is a 1D array containing multiple 1D arrays.
You should be creating the array like this:
Private tiles(32, 24) As PictureBox
And then populating it like this:
For i = 0 To tiles.GetUpperBound(0)
For j = 0 To tiles.GetUpperBound(1)
Dim tile As New PictureBox
'...
tiles(i, j) = tile
Next
Next

Never ever ever use Array as a type name in VB.Net. Instead, you would declare it like this:
Public tiles() As PictureBox
Or this:
Public tiles(32*24) As PictureBox
Or this (probably your best fit):
Public tiles(32, 24) As PictureBox
Or this:
Public tiles As New List(Of PictureBox)
Or skip the extra array altogether, put the controls inside a Panel or GroupBox container, and write code like this when you need to find them:
For Each tile As Picturebox in TilePanel.Controls.OfType(Of PictureBox)()
' ...
Next
Remember, with the move to the .Net ecosystem, VB now works so much better when things are strongly-typed. Option Strict really should be On, and you want very specific type names.

Related

How to create an array of Controls with different types i.e Textbox, combobox, checkbox...based on certain value

VB.net how to create an array of Controls with different types i.e Textbox, combobox, checkbox...based on certain value
This is the code:
Public Function TestControl(c As Integer())
Dim a As Control()
Dim l As Point
Dim F As New Form
For i As Integer = 0 To c.Length - 1
If c(i) Then
a(i) = New TextBox
Else
a(i) = New ComboBox
End If
a(i).Width = 400
a(i).Height = 40
l.Y = 50 + (3 * i - 2) * a(i).Height / 2
l.X = 150
a(i).Location = l
F.Controls.Add(a(i))
Next
F.Show()
Return Nothing
End Function
When I am trying to execute the Function the following Error appears:
Variable 'a' is used before it has been assigned a value. A null reference exception could result at runtime.
I am trying to solve it but i couldn't succeed.
any Idea would very helpful for me
Thanks
To solve your immediate probem of "Variable 'a' is used before it has been assigned a value. A null reference exception could result at runtime."
Your problem is that the line
Dim a As Control()
only creates a variable a that is capable of holding an array of control objects. It doesnt actually create an array, because it doesn't know how many elements to create.
In your situation the solution is straightforward. Change the line to
Dim a(c.Length) As Control
This will create an empty array of controls that you can add your TextBoxes and ComboBoxes.

Type conversion (typecasting). Convert array to matrix (C code to Visual Basic)

I am working at rewriting C code to Visual Basic now. And I got some problems with this syntaxes:
C code:
typedef uint8_t state_t[4][4];
static state_t* state;
void myFunc (uint8_t* output)
{
state = (state_t*)output;
// some actions
}
My Visual Basic code:
Dim state(3, 3) As Byte
Sub myVBFunc(ByRef output() As Byte)
state = output ' does not work: Cannot convert Byte() to Byte(*,*)'
'state = CType(output, Byte(,)) ''also does not work'
' some actions'
End Sub
I can do it in C, because array name is a pointer to the first element. And C can automatically converts this types. So VB cannot. I'm stacked here.
How to convert this array to matrix?
Or how to avoid using of this in VB?
P.S. Actually I work in Visual Basic 6.0. (try to modify old project).
If the question is about VB6, then you have three options:
a. Change everything to use dynamic arrays:
Dim state() As Byte
Sub myVBFunc(ByRef output() As Byte)
state = output
End Sub
You can set up the array to call myVBFunc by redimensioning e.g.:
Dim myarray() as Byte
ReDim myarray(3,3)
myVBFunc(myarray)
b. Embed the fixed size array in a user defined type and pass that around instead:
Type type_state
state(3, 3) As Byte
End Type
Dim state As type_state
Sub test()
Dim something As type_state
myVBFunc something
End Sub
Sub myVBFunc(ByRef output As type_state)
state = output
End Sub
c. Use objects. Set up a class to hold your fixed sized array and set up getters and setters to access it. A short answer would be to long for me to show in this post.
(You will need extra code to set up the array itself)
I used simple way: just assign it trough the loop using index multiplication.
For k = 0 To 3
For j = 0 To 3
state(k, j) = temp(4 * k + j)
Next j
Next k
Why I didn't use Guillermo Phillips's answer:
a. I can't replace state(3,3) from my question just as
Dim state() As Byte
because there is some specific math here which is really simple for matrices.
I found useful ReDim option. Especially when use it in this way:
ReDim Preserve input(15)
It saves previous values of input array or put zeros in new positions!
But we can convert array to matrix using ReDim:
ReDim cannot change the number of dimensions
b. Idea of using of user defined type is really interesting but I stall can't figure out how to assign then Byte() to my
Type type_state
state(3, 3) As Byte
End Type
c. Agree! This way is useful. I just avoid it because of it's complicity (much easier to create function with inbuilt loop). But maybe using object is more safety?..

How to declare a 2D array to store pictures (using picture boxes)

I am designing a Breakout style game for a project that I am currently working on. I have just finished implementing the ball and the paddle and am having some trouble implementing the bricks for the game. I have a picture of a brick that I want to put in the game. For this, as I need a grid of bricks, I was thinking of declaring a 2D array of pictureboxes (so I can assign the picture of the brick) but I have only been able to declare the array. This is the line of code I have:
Dim Bricks(9, 9) As PictureBox
So, my question is: How do I access each picturebox and assign the image of the brick? and is there a quicker way to do it? Thanks, your help will be very much appreciated.
Note that after you create the Bricks array, this array is still empty, i.e. all its elements are Nothing. You will need to assign the PictureBoxes that are on your form to this array, unless you want to go the other way round and create the picture boxes dynamically.
In the first case do something like this:
Bricks(0,0) = pictureBox1
Bricks(0,1) = pictureBox2
...
Or with loops
For x As Integer = 0 To 9
For y As Integer = 0 To 9
Bricks(x, y) = Controls("pictureBox" & (10 * x + y))
Next
Next
Or (10 * y + x) depending on the order you have chosen.
In the other case (create the picture boxes automatically)
For x As Integer = 0 To 9
For y As Integer = 0 To 9
'Create and initialize the PictureBox
Dim pb AS New PictureBox
pb.Size = New Size(30, 30)
pb.Location = New Point(20 + 30 * x, 20 + 30 * y)
pb.Image = myinitialImage
AddHandler pb.Click, AddressOf HandlePictureClick
'Assign the PictureBox to the array
Bricks(x, y) = pb
'Add the PictureBox to the Form
Controls.Add(pb)
Next
Next
Now you can assign a picture like this
Bricks(x, y).Image = myPicture

How to iterate an array of a dynamic size in a loop

I am using VB.NET.
I would like have an array called A1 and I will perform for loop inside that array.
In the middle of the for loop, I need to remove an item from that A1 array.
I am aware that if I remove that object from A1 array, the program will crash (out of bounds error message).
Which array variable in VB.NET would allow me to perform the task above?
Code sample is most welcomed!
Thank you.
The easiest way would be to use a list instead of an array (or convert the array you have to a List(of T).
The trick then is to move from the end of the list to the front instead of the other way around.
For example:
Sub Main()
Dim RndGenerator as New Random
Dim a As New List(Of Double)
For i = 0 To 99
a.Add(RndGenerator.NextDouble() * 10) 'Populate the list
Next
For i = a.Count - 1 To 0 Step -1 'This loop performs the deletion.
If a(i) > 5 Then a.RemoveAt(i)
Next
Console.ReadKey() 'Or debugger.Break to look at the result
End Sub
This will populate a list with random numbers from 0 to 10. It then removes all numbers >5 from the list.
Edit:
Good point from Steven Doggart on not using VB6 Relics. Edited the code to use the System.Random class instead.

VB.NET - For Each loop not changing elements in an array of class

I'm using an array of class; the class is very simple and only contains one element. The class is declared as follows:
Class Cell
Public Info As Int16
End Class
The array:
Dim Maze(11, 15) As Cell
I want to use a simple sub to set the .Info variable for every element to 15, but I realise I have to create the elements first. I tried using a For Each loop as follows, but it didn't work, when the loop completed everything was still set to nothing:
For Each e As Cell In Maze
If e Is Nothing Then
e = New Cell
End If
Next
I'm not concerned about the correct solution: I used a regular For loop and this accomplishes everything I want done...
For a = 0 To Maze.GetUpperBound(0)
For b = 0 To Maze.GetUpperBound(1)
Maze(a, b) = New Cell
Maze(a, b).Info = Maze(a, b).Info Or 15
Next
Next
...but I'd like to know why the For Each loop didn't work in the first place, as I'm sure there's some fundamental principle I'm missing here.
The reason the For Each loop did not work is because within the For Each construct, the local variable (in your case e) is not a reference, but rather a copy; thus your New Cell has no consequence on your array of Cell.

Resources