Object reference not set to an instance of an object - arrays

The purpose of this program is to run through a range of pictureboxes and set it's .image property to a particular image. I keep getting the error "Object reference not set to an instance of an object". Coming from the line that shows "DirectCast(Me.Controls(pic(i)), PictureBox).Image = My.Resources.glass_buttonred"....Whats weird is if i move that code outside of the for loop it runs just fine.
Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
Dim pic(2) As Object
For i = 0 To 2
pic(i) = "picturebox" + Convert.ToString(i)
DirectCast(Me.Controls(pic(i)), PictureBox).Image = My.Resources.glass_buttonred
Next
Label1.Text = pic(1)
End Sub
HERE IS THE WORKING CODE. THANKS! Hope it will help others wanting to convert string to control object
Dim pic(2) As Object
For i = 0 To 2
pic(i) = "picturebox" + Convert.ToString(i + 1)
DirectCast(Me.Controls(pic(i)), PictureBox).Image = My.Resources.glass_buttonred
Next
Label1.Text = pic(1)

The problem may be that Me.Controls is case sensitive. If you're using the designer to build these, you likely need:
' Note the upper case letters below
pic(i) = "PictureBox" + (i + 1).ToString()
DirectCast(Me.Controls(pic(i)), PictureBox).Image ' ...
The designer, by default, will name the controls "PictureBox1" (for the first), and "PictureBox2" for the second, with the case being relevant.

Related

(VB.NET) display the lower half of a textfile to a listbox

I have to make a application that organizes a list of runners and their teams. In the following text file, I have to remove the top half of the text file (the top half being the listed teams) and display only the bottom half (the runners)in a listbox item.
The Text file:
# School [School Code|School Name|Coach F-Name|Coach L-Name|AD F-Name|AD L Name]
WSHS|Worcester South High School|Glenn|Clauss|Bret|Zane
WDHS|Worcester Dorehty High School|Ellsworth|Quackenbush|Bert|Coco
WBCHS|Worcester Burncoat High School|Gail|Cain|Kevin|Kane
QRHS|Quabbin Regional High School|Bob|Desilets|Seth|Desilets
GHS|Gardner High School|Jack|Smith|George|Fanning
NBHS|North Brookfield High School|Hughe|Fitch|Richard|Carey
WHS|Winchendon High School|Bill|Nice|Sam|Adams
AUBHS|Auburn High School|Katie|Right|Alice|Wonderland
OXHS|Oxford High School|Mary|Cousin|Frank|Daughter
# Roster [Bib #|School Code|Runner's F-Name|Runner's L-Name]
101|WSHS|Sanora|Hibshman
102|WSHS|Bridgette|Moffitt
103|WSHS|Karine|Chunn
104|WSHS|Shanita|Wind
105|WSHS|Fernanda|Parsell
106|WSHS|Albertha|Baringer
107|WSHS|Carlee|Sowards
108|WDHS|Maisha|Kleis
109|WDHS|Lezlie|Berson
110|WDHS|Deane|Rocheleau
111|WDHS|Hang|Hodapp
112|WDHS|Zola|Dorrough
113|WDHS|Shalon|Mcmonigle
I have some code that reads each row from the text file as an array and uses boolean variables to determine where to end the text file. This worked with displaying only the teams, which I've managed to do. But I now need to do the opposite and display only the players, and I'm a bit stumped.
My Code:
Private Sub btnLoadTeams_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnLoadTeam.Click
' This routine loads the lstTeam box from an ASCII .txt file
' # School [School Code | Name | Coach F-Name| Coach L-Name | AD F-Name | AD L-Name]
Dim strRow As String
Dim bolFoundCode As Boolean = False
Dim bolEndCode As Boolean = False
Dim bolFoundDup As Boolean = False
Dim intPosition As Integer
Dim intPosition2 As Integer
Dim strTeamCodeIn As String
Dim textIn As New StreamReader( _
New FileStream(txtFilePath.Text, FileMode.OpenOrCreate, FileAccess.Read))
' Clear Team listbox
lstTeam.Items.Clear()
btnDeleteRunner.Enabled = True
Do While textIn.Peek <> -1 And Not bolEndCode
Me.Refresh()
strRow = textIn.ReadLine.Trim
If Not bolFoundCode Then
If "# SCHOOL " = UCase(Mid(strRow, 1, 9)) Then
bolFoundCode = True
End If
Else
If Mid(strRow, 1, 2) <> "# " Then
For Each item As String In lstTeam.Items
intPosition = InStr(1, strRow, "|")
strTeamCodeIn = Mid(strRow, 1, intPosition - 1)
intPosition2 = InStr(1, item, strTeamCodeIn)
If intPosition2 > 0 Then
bolFoundDup = True
MsgBox("Found Duplicate School Code: " & strTeamCodeIn)
End If
Else
bolEndCode = True
Next
If Not bolFoundDup Then
lstTeam.Items.Add(strRow)
Else
lstTeam.Items.Add("DUPLICATE School Code: " & strRow)
lstTeam.Items.Add("Please correct input file and reload teams")
bolEndCode = True
End If
End If
End If
Loop
End Sub
Ive put bolEndCode = True in between the part that reads the mid section of the text file, but all Ive managed to display is the following in the listbox:
# Roster [Bib #|School Code|Runner's F-Name|Runner's L-Name]
Any help or hints on how I would display just the runners to my "lstPlayers" listbox would be greatly appreciated. I'm a beginner programmer and We've only just started learning about reading and writing arrays in my .NET class.
First I made 2 classes, one Runner and one School. These have the properties available in the text file. As part of the class I added a function that overrides .ToString. This is for he list boxes that call .ToString for display.
Next I made a function that reads all the data in the file. This is very simple with the File.ReadLines method.
Then I created 2 variables List(Of T) T stands for Type. Ours Types are Runner and School. I used List(Of T) instead of arrays because I don't have to worry about what the size of the list is. No ReDim Preserve, just keep adding items. The FillList method adds the data to the lists. First I had to find where the schools ended and the runners started. I used the Array.FindIndex method which is a bit different because the second parameter is a predicate. Check it out a bit. Now we know the indexes of the lines we want to use for each list and use a For...Next loop. In each loop an instance of the class is created and the properties set. Finally the new object is added to the the list.
Finally we fill the list boxes with a simple .AddRange and the lists.ToArray. Note that we are adding the entire object, properties and all. The neat thing is we can access the properties from the listbox items. Check out the SelectedIndexChanged event. You can do the same thing with the Runner list box.
Sorry, I couldn't just work with your code. I have all but forgotten the old vb6 methods. InStr, Mid etc. It is better when you can to use .net methods. It makes your code more portable when the boss says "Rewrite the whole application in C#"
Public Class Runner
Public Property BibNum As Integer
Public Property SchoolCode As String
Public Property FirstName As String
Public Property LastName As String
Public Overrides Function ToString() As String
'The listbox will call .ToString when we add a Runner object to determin what to display
Return $"{FirstName} {LastName}" 'or $"{LastName}, {FirstName}"
End Function
End Class
Public Class School
Public Property Code As String
Public Property Name As String
Public Property CoachFName As String
Public Property CoachLName As String
Public Property ADFName As String
Public Property ADLName As String
'The listbox will call .ToString when we add a School object to determin what to display
Public Overrides Function ToString() As String
Return Name
End Function
End Class
Private Runners As New List(Of Runner)
Private Schools As New List(Of School)
Private Function ReadData(path As String) As String()
Dim lines = File.ReadLines(path).ToArray
Return lines
End Function
Private Sub FillLists(data As String())
Dim location = Array.FindIndex(data, AddressOf FindRosterLine)
'The first line is the title so we don't start at zero
For index = 1 To location - 1
Dim SplitData = data(index).Split("|"c)
Dim Schl As New School
Schl.Code = SplitData(0)
Schl.Name = SplitData(1)
Schl.CoachFName = SplitData(2)
Schl.CoachLName = SplitData(3)
Schl.ADFName = SplitData(4)
Schl.ADLName = SplitData(5)
Schools.Add(Schl)
Next
For index = location + 1 To data.GetUpperBound(0)
Dim SplitData = data(index).Split("|"c)
Dim Run As New Runner
Run.BibNum = CInt(SplitData(0))
Run.SchoolCode = SplitData(1)
Run.FirstName = SplitData(2)
Run.LastName = SplitData(3)
Runners.Add(Run)
Next
End Sub
Private Function FindRosterLine(s As String) As Boolean
If s.Trim.StartsWith("# Roster") Then
Return True
Else
Return False
End If
End Function
Private Sub FillListBoxes()
Dim arrRunners As Runner() = Runners.ToArray
Dim arrSchools As School() = Schools.ToArray
ListBox1.Items.AddRange(arrSchools)
ListBox2.Items.AddRange(arrRunners)
End Sub
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim arrRunner = ReadData("Runners.txt")
FillLists(arrRunner)
FillListBoxes()
End Sub
Private Sub ListBox1_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ListBox1.SelectedIndexChanged
Dim Schl = DirectCast(ListBox1.SelectedItem, School)
TextBox1.Text = Schl.CoachLName
TextBox2.Text = Schl.Code
End Sub

How to monitor array's and reset when limit is reached. VB.net

I have a VB.Net program that loops through array's to try to figure out where bottles are on a "conveyor". The point of this program is to visually show staff, how the conveyor works using VB.net and Labels. It's extremely difficult to explain, so I’ll do my best.
Bottle_Number(10) Bottle_Position(128)
There are 10 bottles that I want to track at all 128 stops on the conveyor.
We have a conveyor that can only fit 10 bottles. I need to track the position of each of the 10 bottles. Once bottle 11 comes on - That means bottle 1 is completed and off the conveyor. So, bottle 11 becomes bottle 1, so I need to reset the position of bottle1 to 0, and continue tracking bottles 2-9 while also tracking bottle 11(Not bottle 1). Once bottle 12 comes on it becomes bottle 2, and I need to reset the position of bottle 2 to '0' and continue tracking all bottles.
Any help would be appreciated.
Here is my code:
Public Class frmMain
Dim Product_Position(10) As Integer
Dim Inches_Per_Pulse As Integer
Dim PulseNumber As Integer
Dim Product_Counter As Integer
Dim Product_Location(10) As Integer
Dim Function1 As Integer
Dim Function2 As Integer
Dim Function3 As Integer
Dim Function4 As Integer
Dim Function5 As Integer
Dim Function6 As Integer
Dim Function7 As Integer
Dim Function8 As Integer
Dim Function9 As Integer
Dim Function10 As Integer
Dim Product_in_Tunel As Integer
Dim test As Integer
Dim Roll_OVer As Boolean
Dim Product_Counter_Test As Integer
Private Sub btnStart_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnStart.Click
lblStatus.BackColor = Color.Green
lblStatus.Text = "Conveyor Status: Running"
End Sub
Private Sub btnStop_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnStop.Click
lblStatus.BackColor = Color.Red
lblStatus.Text = "Conveyor Status: Off"
End Sub
Private replace_next As Integer
Private Sub btnSend_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSend.Click
If Product_Counter = 10 Then
replace_next += 1
If replace_next > 10 Then
replace_next = 1 ' replace them in turn 1..10, then loop back to 1
Product_Position(replace_next) = 0 ' put initial position here
End If
End If
Product_Counter = Product_Counter + 1
If Product_Counter > 10 Then
Product_Counter = 1
Roll_over = True
End If
'MsgBox(Product_Counter)
'MsgBox(replace_next)
End Sub
Private Sub btnPulse_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnPulse.Click
Get_Location()
End Sub
Private Sub frmMain_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
PulseNumber = "0"
Inches_Per_Pulse = "1"
Roll_OVer = False
'MsgBox("Test")
End Sub
Public Sub Get_Location()
'MsgBox(Product_Counter)
If Roll_OVer = True Then
Product_Counter_Test = 10
'MsgBox("i'm stuck here")
End If
If Roll_OVer = False Then
Product_Counter_Test = Product_Counter
End If
'MsgBox(Product_Counter_Test)
'MsgBox("am I here - Yes")
For test = 1 To Product_Counter_Test
'MsgBox("This works")
Product_Position(test) = Product_Position(test) + Inches_Per_Pulse
Next
PulseNumber = PulseNumber + 1
ClearLabels()
lblProduct1Position.Text = Product_Position(1)
lblProduct2Position.Text = Product_Position(2)
lblProduct3Position.Text = Product_Position(3)
lblProduct4Position.Text = Product_Position(4)
lblProduct5Position.Text = Product_Position(5)
lblProduct6Position.Text = Product_Position(6)
lblProduct7Position.Text = Product_Position(7)
lblProduct8Position.Text = Product_Position(8)
lblProduct9Position.Text = Product_Position(9)
lblProduct10Position.Text = Product_Position(10)
End Sub
Public Sub ClearLabels()
lblProduct1Position.Text = ""
lblProduct2Position.Text = ""
lblProduct3Position.Text = ""
lblProduct4Position.Text = ""
lblProduct5Position.Text = ""
lblProduct6Position.Text = ""
lblProduct7Position.Text = ""
lblProduct8Position.Text = ""
lblProduct9Position.Text = ""
lblProduct10Position.Text = ""
End Sub
The Pulse button is what is actually driving the conveyor, each pulse (click of the button) means the conveyor is moving forward.
Right now once the program gets to bottle 11, it resets and only moves forward the "new" bottle (bottle1). It should continue incrementing the remaining bottles until they reach the end and do the same for them - Reset the position to 0 and begin counting again.
As far as I understand it, once you have 11 bottles, you don't want to reset to only one bottle, but instead still have 10 bottles, and replace one of them. You'll need a second variable to keep track of which is to be replaced.
So instead of :
Private Sub btnSend_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSend.Click
Product_Counter = Product_Counter + 1
If Product_Counter > 10 Then Product_Counter = 1
End Sub
It would be something like:
Private Replace_Next as Integer = 0
Private Sub btnSend_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSend.Click
If Product_Counter = 10 Then
Replace_Next += 1
If Replace_Next > 10 Then Replace_Next = 1 ' replace them in turn 1..10, then loop back to 1
Product_Position(Replace_Next) = .... ' put initial position here
Else
Product_Counter = Product_Counter + 1
End If
End Sub
Your conveyor is FIFO (first-in, first-out), so rather than constantly shifting, reindexing and/or rebuilding (=reset?) an array to make it seem like it is FIFO, Net includes the Queue(Of T) collection which is FIFO.
A LinkedList(Of T) could also be used. A plain List(Of T) would also work, but if the add/remove frequency is high, that will result in the same inefficient shifting taking place under the hood that you have with an array.
The only issue is enforcement of the size limit, which is easily handled with a small class wrapper. I assume there is something interesting or identifiable about the bottles other than their position. The test code uses a sequence ID and the contents.
Friend Class Bottle
Public Property Contents As String
Public Property SequenceID As Int32
' etc
Public Overrides Function ToString() As String
Return String.Format("{0}: ({1})", SequenceID.ToString("00"), Contents)
End Function
End Class
You likely have more relevant information to show. The, the collection class:
Friend Class BottleQueue
Private mcol As Queue(Of Bottle)
Private lbls As Label()
Private MaxSize As Int32 = 10 ' default
Public Sub New(size As Int32)
MaxSize = size
mcol = New Queue(Of Bottle)
End Sub
Public Sub New(size As Int32, l As Label())
Me.New(size)
lbls = l
End Sub
Public Sub Add(b As Bottle)
mcol.Enqueue(b)
Do Until mcol.Count <= MaxSize
mcol.Dequeue()
Loop
UpdateDisplay()
End Sub
Public Function Peek() As Bottle
Return mcol.ElementAtOrDefault(0)
End Function
Public ReadOnly Property Count() As Int32
Get
Return mcol.Count
End Get
End Property
Public Function Remove() As Bottle
Dim b As Bottle = Nothing
If mcol.Count > 0 Then
b = mcol.Dequeue
UpdateDisplay()
End If
Return b
End Function
Private Sub UpdateDisplay()
Dim n As Int32
If lbls Is Nothing OrElse lbls.Count = 0 Then
Return
End If
For n = 0 To mcol.Count - 1
lbls(n).Text = mcol.ElementAtOrDefault(n).ToString
Next
For n = n To lbls.Count - 1
lbls(n).Text = "(empty)"
Next
End Sub
Public ReadOnly Property GetQueue As Bottle()
Get
Return mcol.ToArray()
End Get
End Property
End Class
The class has 2 display means built in. One updates a set of labels. Since it is a collection, it also provides a way to get the current collection in order for a collection type control such as a Listbox. An even better way would be if the collection itself was "observable", so it could be used as a datasource.
It also provides a way to Removethe next bottle manually. Removing from a specific index (e.g. Remove(3)) is antithetical to a Queue, so it isnt implemented.
test code:
' form level vars:
Private BottleQ As BottleQueue
Private BottleID As Int32 = 7
' form load, passing the labels to use
' using a queue size of FIVE for test
BottleQ = New BottleQueue(5, New Label() {Label1, Label2, Label3, Label4, Label5})
Adding an item:
Dim material = {"Napalm", "Beer", "Perfume", "Pepsi", "Cyanide", "Wine"}
' add new bottle with something in it
BottleQ.Add(New Bottle With {.Contents = material(RNG.Next(0, material.Count)),
.SequenceID = BottleID})
BottleID += 1
' clear and show the contents in a listbox:
lbQueView.Items.Clear()
lbQueView.Items.AddRange(BottleQ.GetQueue)
The BottleId arbitrarily starts at 7, the contents are random. BTW, material shows just about the only way I ever use an array: when the contents are fixed and known ahead of time. In almost all other cases, a NET collection of one sort or another, is probably a better choice.
Because it is not an observable collection (and that is a little at odds with the FIFO nature), the listbox needs to be cleared each time. That could be internal to the class like the label display is. Results:
On the right, the first 5 are shown in order; 3 clicks later, the result is on the left: everything moved up 3 and 3 new items have been added.
Note: If the code using this needs to know when/which Bottle is removed from the conveyor, the class could include a ItemRemoved event which provides the item/Bottle just removed when adding forces one out. That is probably the case, but the question doesnt mention it.

Getting Multi Rows in Database and transferring it in a multiline textbox in VB.net WinForms

Here in my code, i have a database which has table of my applicants. As you will see in the code below, i want to get the number of rows from my command text and transfer it to the string "abc"
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
myr.Close()
mycom.Connection = cn
mycom.CommandText = "SELECT Count(Cellphone) FROM tbl_applicant where Gender='Female';"
myr = mycom.ExecuteReader
Dim abc As String
If myr.Read Then
abc = myr(0)
End If
myr.Close()
On the code Below i used the abc as the number of data i must acquire. Then i used the new query to get the values i wanted to and transfer them to a String Array, as you can see I Redim the universal variable Numb to abc to have its array boundery.
mycom.CommandText = "SELECT Cellphone FROM tbl_applicant where Gender='Female';"
myr = mycom.ExecuteReader
ReDim Numb(abc)
If myr.Read Then
For i As Integer = 1 To abc.ToString - 1
LOT = myr(0).ToString
LOT = LOT + (myr(i).ToString + ",") <- this is where i get the error it says that index is our of range.
Numb = LOT.Split(",")
Next
End If
In this code below, i want the values of Variable Numb() to be transferred to a multiline textbox
Dim sbText As New System.Text.StringBuilder(500)
For i As Integer = 0 To Numb.Length - 2
' This will convert the number to a string, add it to the stringbuilder
' and then append a newline to the text buffer
sbText.AppendLine(Numb(i))
Next i
' Now move the buffer into the control
TextBox1.Text = sbText.ToString()
End Sub
The end value i must see in the textbox should be like
11111111111
11111111112
11111111113
11111111114
and so forth, please try to understand the numbers i am referring it to real phone numbers. Any help with the problem or solution maybe.. Thanks
I don't think you need to first query the db to get the count of records before then going back to the db to get the phonenumbers, you could just do this:
mycom.CommandText = "SELECT Cellphone FROM tbl_applicant where Gender='Female';"
myr = mycom.ExecuteReader
While myr.Read()
TextBox1.Text = TextBox1.Text & myr(0) & Environment.NewLine
End While
No need for array's or List's
While this is just a rough guide and an attempt at understanding your issue, try the code and see if it works for you.

How to respond to events for objects in an array

I have made an array of tiles (pictureboxes) in an array and need them to all do something when clicked, but don't know how. Specifically, I want to be able to place some other object on them by clicking a tile and making that object go to that tile's location. I know you may suggest looking at the mouseposition variable and having some invisible box over all the tiles to register clicks, but I would like to know how to register any event for an object in an array for anything that comes up in the future. I do know how to register events for objects which aren't in an array by the way.
The object I want to move on top of the picturebox will also be from an object array, but a different one.
Here is my code:
Public Class Form1
Dim tiles(50) As PictureBox 'This is the object array of tiles
Dim plants() As String 'I haven't set this up yet, but this will be for the objects to be 'placed' on the pictureboxes.
Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
Dim tileWidth As Integer = 50
Dim tileHeight As Integer = 50
Dim xindent As Integer = 10
Dim yindent As Integer = 10
For x = 0 To 9
For y = 0 To 4
ReDim Preserve tiles(x * y)
tiles(x * y) = New PictureBox With {.Visible = True, .Size = New System.Drawing.Size(50, 50), .Parent = Me, .BackColor = Color.GreenYellow, .Image = Nothing}
tiles(x * y).Location = New System.Drawing.Point(x * tileWidth + xindent, y * tileHeight + yindent)
If (x Mod 2 = 0 And y Mod 2 = 0) Or (x Mod 2 <> 0 And y Mod 2 <> 0) Then
tiles(x * y).BackColor = Color.Green
End If
Next
Next
End Sub
End Class
I simply don't know how to set up the click event handler for the array of tiles so that's why its not in the code above.
Thanks in advance for your help.
AddHandler is there for that. After the New you just need to attach a function to the event
AddHandler tiles(x * y).Click, AddressOf Tile_Click
And have a function that handles the event
Private Sub Tile_Click(sender As Object, e As System.EventArgs)
' sender represent the reference to the picture box that was clicked
End Sub
If you already know the size of the array, you should ReDim your array just once instead of each time you loop (Move the ReDim out of the loops). Also, since y is 0 on the first loop, you are basically doing a ReDim of 0 elements (x*y = 0 when y = 0)
the_lotus has already given you a great answer.
Just wanted to share a trick I often use when wiring up events with AddHandler.
Declare a temporary variable using WithEvents in your class:
Public Class Form1
Private WithEvents Tile As PictureBox
...
Now, in the two DropDowns across the top of code editor, change Form1 to Tile, and (Declarations) to Click (or whatever event you want). This will enter a method for you that has the correct method signature:
Private Sub Tile_Click(sender As Object, e As EventArgs) Handles Tile.Click
End Sub
Delete the Handles Tile.Click portion that appears at the end of the first line:
Private Sub Tile_Click(sender As Object, e As EventArgs)
End Sub
Finally, remove your temporary declaration that used WithEvents.
Now you've got a method with the correct signature that you can use with AddHandler. This is very handy for events that don't have the standard signature.

Deleting Lines from Array

I have an array of lines and I want at some point to erase some of them.
Here's a sample of the code:
Dim canvas As New Microsoft.VisualBasic.PowerPacks.ShapeContainer
Dim lines(20) As PowerPacks.LineShape
Dim it As Integer = 0
Private Sub GoldenSpi_Load(sender As Object, e As EventArgs) Handles MyBase.Load
canvas.Parent = Me
lines.Initialize()
iter.Text = 0
End Sub
Private Sub iter_TextChanged(sender As Object, e As EventArgs) Handles iter.TextChanged
If (it > iter.Text And iter.Text <> 0) Then
ReDim Preserve lines(iter.Text - 1)
End If
If (it <> iter.Text) Then
it = iter.Text
End If
For i As Integer = 1 To iter.Text
lines(i - 1) = New PowerPacks.LineShape(canvas)
lines(i - 1).StartPoint = pA(i)
lines(i - 1).EndPoint = pB(i)
lines(i - 1).BringToFront()
Next
End Sub
After I execute the program, the lines are created. But when I give a value to my textbox that is smaller than the variable 'it', it justs delete the last line and not the rest. Also I saw while debugging that the size of array is reduced. So that means that the contents beyond the size are still kept? Why is that?. Any help is appreciated. Thanks.
EDIT: I tried to create the List like this:
Dim lines As New Generic.List(Of PowerPacks.LineShape)
Private Sub iter_ValueChanged(blabla) Handles iter.ValueChanged
If (it > iter.Value And iter.Value <> 0) Then
lines.RemoveRange(iter.Value - 1, lines.Count - iter.Value)
End If
For i As Integer = 1 To iter.Value
InitPoints()
If i - 1 = lines.Count Then
Dim line As New PowerPacks.LineShape
With line
.StartPoint = pA(i)
.EndPoint = pB(i)
.BringToFront()
.Parent = canvas
End With
lines.Add(line)
End If
Next
End Sub
But still the lines are visible in the form. I debugged it and saw that the list size decreased. The same problem when I had an array. What is going?...
I recommend changing iter.Text to cint(iter.Text), as there is a chance it's comparing both values as text (which is compared differently).
I'd also recommend changing Dim lines(20) As PowerPacks.LineShape to Dim lines As new generic.list(of PowerPacks.LineShape)
That way you don't have to worry about ReDim Preserve (which can be slow when you do it in a loop), and you can easily insert items into any index if you whish
You should use Option Strict On in your project, in order to avoid implicit conversion between types which can give you errors or, worse, unexpected behaviors.
On the other hand, you should not have a TextBox to store numbers unless there is a need. Use a NumericUpDown, for example. Take a look at the MSDN Documentation.
And now, for the array, I recommend using a List, which has all the methods implemented that you need to handle the elements, and has a .ToArray() method that will give you the array if needed.
Try something like this:
Dim it As Integer = 0
Dim lines As New List(Of PowerPacks.LineShape)()
Sub iter_TextChanged(sender As Object, e As EventArgs) Handles iter.TextChanged
Dim iTxt As Integer
Try
iTxt = Integer.Parse(iter.Text)
If it > iTxt AndAlso iTxt <> 0 Then
End If
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
End Sub
I was going to write to you an example, but I realized that I don't know exactly what you're trying to do. Could you explain?

Resources