Adding Conditions to the Listboxes from .csv files - vb.net

enter image description herei am looking for this problem for very long time and I have found nothing about that... :( .
So, I have 2 .csv files. In the .csv file 1 are the listboxes and all of these listboxes have one number between 1 and 6. In the .csv file 2 are some tools like (audi, bmw) and the tools have one numer between 1 and 6 too.
Example:
.csv file 1
Listbox 1 (X,Y,Length,Width) category 1
Listbox 2 (X,Y,Length,Width) category 2
Listbox 3 (X,Y,Length,Width) category 3
.csv file 2
Mercedes category 1
BMW category 2
Audi category 3
So, I want compare the 2 .csv files and allow the listbox 2 for only BMW to drag and drop.
If I drop categroy 2 to category 1 in the listbox, it should be false.
Imports System.Windows.Forms
Imports System.IO
Public Class Form2
Private meineListBoxen As New List(Of ListBox)
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load
Dim strZeilen() As String
Dim strFelder() As String
Dim strZeilen0() As String
Dim strZeilen2() As String = IO.File.ReadAllLines("K:\Ruebel_Andreas\Modellpflege\Datenerfassung.csv")
Dim strFelder1() As String
strZeilen = File.ReadAllLines("K:\Ruebel_Andreas\Modellpflege\listboxpflege.csv")
strZeilen0 = IO.File.ReadAllLines("K:\Ruebel_Andreas\Modellpflege\Spritzguss.csv")
For i As Integer = 1 To strZeilen.GetUpperBound(0)
strFelder = strZeilen(i).Split(";")
meineListBoxen.Add(New ListBox)
With meineListBoxen(i - 1)
.Left = strFelder(0)
.Top = strFelder(1)
.Width = strFelder(2)
.Height = strFelder(3)
End With
Me.Controls.Add(meineListBoxen(i - 1))
Me.meineListBoxen(i - 1).AllowDrop = True
AddHandler meineListBoxen(i - 1).MouseDown, AddressOf meineListbox_MouseDown
AddHandler meineListBoxen(i - 1).DragDrop, AddressOf meineListbox_DragDrop
AddHandler meineListBoxen(i - 1).DragEnter, AddressOf meineListbox_DragEnter
Next
For a As Integer = 0 To strZeilen0.GetUpperBound(0)
Me.meineListBoxen(1 - 1).Items.Add(strZeilen0(a).Substring(0, strZeilen0(a).IndexOf(";")))
Next
For j As Integer = 1 To strZeilen2.GetUpperBound(0)
strFelder1 = strZeilen2(j).Split(" ")
With meineListBoxen(j)
.Items.Add(strFelder1(4))
End With
For Each itm In meineListBoxen(j).Items
If meineListBoxen(1 - 1).Items.Contains(itm) Then meineListBoxen(1 - 1).Items.Remove(itm)
Next
Next
End Sub
Private Sub Form1_MouseMove(sender As Object, e As MouseEventArgs) Handles Me.MouseMove
Me.lblMaus.Text = "X: " & e.X & " , Y:" & e.Y
End Sub
Private source As ListBox
Private sourceIndex As Integer
Private Sub meineListbox_MouseDown(ByVal sendre As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs)
Dim aPoint As Point
Dim lbx As ListBox
Dim aIndex As Integer
lbx = CType(sendre, ListBox)
aPoint = New Point(e.X, e.Y)
aIndex = lbx.IndexFromPoint(aPoint)
Try
If aIndex <= 0 Then
source = lbx
sourceIndex = aIndex
lbx.DoDragDrop(lbx.Items(aIndex), DragDropEffects.All)
End If
Catch ex As Exception
MessageBox.Show("Bitte wählen Sie ein Werkzeug aus")
End Try
End Sub
Private Sub meineListbox_DragDrop(ByVal sender As System.Object,
ByVal e As System.Windows.Forms.DragEventArgs)
Dim lbx As ListBox
lbx = CType(sender, ListBox)
If Not source Is Nothing Then
source.Items.RemoveAt(sourceIndex)
End If
lbx.Items.Add(e.Data.GetData(DataFormats.Text))
End Sub
Private Sub meineListbox_DragEnter(ByVal sender As System.Object,
ByVal e As System.Windows.Forms.DragEventArgs)
If (e.Data.GetDataPresent(DataFormats.Text)) Then
e.Effect = DragDropEffects.All
Else
e.Effect = DragDropEffects.None
End If
End Sub
Private Sub cmdSave_Click(ByVal sender As Object, ByVal e As EventArgs) Handles Speichern.Click
Dim w As New IO.StreamWriter("K:\Ruebel_Andreas\Modellpflege\Datenerfassung.csv")
For i = 0 To meineListBoxen.Count - 1
w.WriteLine(meineListBoxen.Item(i))
Next
w.Close()
End Sub
Private Sub WerkzeugHinzufügen_Click(sender As Object, e As EventArgs) Handles WerkzeugHinzufügen.Click
Process.Start("K:\Ruebel_Andreas\Modellpflege\Spritzguss.csv")
End Sub
Private Sub StellplatzHinzufügen_Click(sender As Object, e As EventArgs) Handles StellplatzHinzufügen.Click
Process.Start("K:\Ruebel_Andreas\Modellpflege\listboxpflege.csv")
End Sub
End Class

Private Sub cmdSave_Click(ByVal sender As Object, ByVal e As EventArgs) Handles Speichern.Click
Using w As New StreamWriter("K:\Ruebel_Andreas\Modellpflege\Datenerfassung.csv")
For i = 0 To meineListBoxen.Count - 1
w.WriteLine(meineListBoxen.Item(i))
Next
End Using
End Sub
I find it odd that the Handles clause does not match the name of the method. The default would be Private Sub Speichern_Click
StreamWriter needs to be disposed. Using...End Using blocks will handle this even if there is an error.
Let's say you have 3 list boxes. Your loop will go from index 0 to index 2. WriteLine will call ToString on each item in the list of ListBox. I don't believe that a ListBox provides an implementation of ToString so you will get the fully qualified name of the object's type. I don't think you want this.
Private Sub cmdSave_Click(ByVal sender As Object, ByVal e As EventArgs) Handles Speichern.Click
Using w As New StreamWriter("K:\Ruebel_Andreas\Modellpflege\Datenerfassung.csv")
For Each LB As ListBox In meineListBoxen
For Each item As String In LB.Items
w.WriteLine(item)
Next
Next
End Using
End Sub
You can initialize your variables as you declare them and with Option Infer they will be strongly typed (only works for local variables.
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load
Dim strZeilen2 = File.ReadAllLines("K:\Ruebel_Andreas\Modellpflege\Datenerfassung.csv")
Dim strZeilen = File.ReadAllLines("K:\Ruebel_Andreas\Modellpflege\listboxpflege.csv")
Dim strZeilen0 = File.ReadAllLines("K:\Ruebel_Andreas\Modellpflege\Spritzguss.csv")
For i = 1 To strZeilen.GetUpperBound(0) 'Why are skipping the first line?
Dim strFelder = strZeilen(i).Split(";"c)
Dim LB As New ListBox
With LB
.Left = CInt(strFelder(0))
.Top = CInt(strFelder(1))
.Width = CInt(strFelder(2))
.Height = CInt(strFelder(3))
.AllowDrop = True
.Name = "ListBox" & i 'In case you need to refer to the control be name
End With
If i = 1 Then
For a As Integer = 0 To strZeilen0.GetUpperBound(0)
LB.Items.Add(strZeilen0(a).Substring(0, strZeilen0(a).IndexOf(";")))
Next
End If
AddHandler LB.MouseDown, AddressOf meineListbox_MouseDown
AddHandler LB.DragDrop, AddressOf meineListbox_DragDrop
AddHandler LB.DragEnter, AddressOf meineListbox_DragEnter
'I fleshed out the control before adding to the collections
Controls.Add(LB)
meineListBoxen.Add(LB)
Next
For j = 1 To strZeilen2.GetUpperBound(0) 'Again skipping first line, perhaps it is a title line
Dim strFelder1 = strZeilen2(j).Split(" "c)
meineListBoxen(j).Items.Add(strFelder1(4)) 'You are skipping the first list box
For Each itm In meineListBoxen(j).Items
If meineListBoxen(0).Items.Contains(itm) Then
meineListBoxen(0).Items.Remove(itm)
End If
Next
Next
End Sub
No need to define a point, just pass the coordinates to the IndexFromPoint method. You can use DirectCast to get the ListBox since we are sure the sender is a ListBox. DirectCast skips some of the checks that CType does so the method so is a bit faster. I am not sure if the check on the value of aIndex is necessary. Exception handling is heavy and shouldn't be used for a simple value check.
Private Sub meineListbox_MouseDown(sender As System.Object, e As System.Windows.Forms.MouseEventArgs)
Dim lbx = DirectCast(sender, ListBox)
Dim aIndex = lbx.IndexFromPoint(e.X, e.Y)
If aIndex < 0 Then
MessageBox.Show("Bitte wählen Sie ein Werkzeug aus")
Else
source = lbx
sourceIndex = aIndex
lbx.DoDragDrop(lbx.Items(aIndex), DragDropEffects.All)
End If
End Sub
Use IsNot when checking for null objects.
Private Sub meineListbox_DragDrop(sender As System.Object, e As System.Windows.Forms.DragEventArgs)
Dim lbx = DirectCast(sender, ListBox)
If source IsNot Nothing Then
source.Items.RemoveAt(sourceIndex)
End If
lbx.Items.Add(e.Data.GetData(DataFormats.Text))
End Sub
Updating this label over and over will just slow things down. Delete this Sub.
'Private Sub Form1_MouseMove(sender As Object, e As MouseEventArgs) Handles Me.MouseMove
'lblMaus.Text = "X: " & e.X & " , Y: " & e.Y
'End Sub
I can't help more without correct data from your files. At one point, you are splitting by a semicolon and there aren't any in your sample data! The file content you showed is certainly not a CSV file.

Related

Create a undo/redo textboxes algorithm in VB.Net

I would love to create a type algorithm Undo/Redo in VB.Net, first at least i want to make the undo.
if we have the example Textbox1.Text = a,b,c
then change to = a,b,c,e
then change to = a,b,c,f
when I click on undo I want to display (that is, the value before it. before after a,b, c, f, was a, b, c,e
a,b,c,e
and when I click once again I want to display
a,b,c
that is, an undo / redo algorithm of added values
I first created a global list.
Public Module Globals
Public Undo As New List(Of String)
End Module
if Textboxes value is not exists in the list, then I will add it.
Private Sub Button1(sender As Object, e As EventArgs) Handles Button1.Click
If Undo IsNot TextBox1.Text Then
Undo.Add(TextBox1.Text)
End If
End Sub
hey well here's the tricky part
Private Sub Undo_Click(sender As Object, e As EventArgs) Handles Undo.Click
Dim i as integer = Undo.Count
While TextBox1.Text IsNot Undo(i)
TextBox1.Text = Undo(i)
End While
End Sub
For i As Integer = Undo.Count To 0 Step -1
TextBox1.Text = Undo(i)
Next
unfortunately no such loop works in this case.
Try this:
Private Undos As List(Of String) = New List(Of String)()
Private AddUndo As Boolean = True
Private Sub textBox1_TextChanged(ByVal sender As Object, ByVal e As EventArgs)
If AddUndo = True Then
Undos.Add(textBox1.Text)
End If
End Sub
Private Sub button1_Click(ByVal sender As Object, ByVal e As EventArgs)
If Undos.Count <> 0 Then
AddUndo = False
If Undos.Count > 1 Then
textBox1.Text = Undos(Undos.Count - 2)
Undos.RemoveAt(Undos.Count - 1)
Else
textBox1.Text = ""
Undos.RemoveAt(0)
End If
AddUndo = True
End If
End Sub

loop through list box in vb and get a total amount

I’m trying to loop through a list of prices on a list box and print the total in a textbox on the form. The loop I have works, but the figures it produces are all wrong!. can any one help me??
the figures look ok but then when i add more items to the list box the total amount goes all wrong.
Public Class f
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
'TODO: This line of code loads data into the 'LoftDataSet.Services' table. You can move, or remove it, as needed.
Me.ServicesTableAdapter.Fill(Me.LoftDataSet.Services)
'Loop through all the rows that are in the dataset
For Each dr As DataRow In LoftDataSet.Services.Rows
Dim btn As New Button 'Instantiate a button
btn.Text = dr("service_name").ToString 'UserName is a field in my Users Table
btn.Size = New Size(140, 80)
btn.Tag = dr("ID") 'Here we set the tag to the primary key (ID)
'Since we're using a flowlayoutpanel, we don't need to worry about setting the location property
FlowLayoutPanel1.Controls.Add(btn) 'Add the button to the flow layout panel
AddHandler btn.Click, AddressOf UserClick 'Here we give the button a handler for the click event
Next
End Sub
Public Class Product
Public Property ProductName As String
Public Property ProductCost As Decimal
Public Overrides Function ToString() As String
Return ProductCost & " " & ProductName
'Here you could build a formatted string to the user to include cost
End Function
End Class
'Here we write our method for the click event of the button(s) we created
Dim SelectedProduct As New Product
Private Sub UserClick(ByVal sender As Object, ByVal e As EventArgs)
'We set a filter to the binding source passing it ID=<and whatever is stored in the tag property>
ServicesBindingSource.Filter = "ID = " & DirectCast(sender, Button).Tag.ToString
SelectedProduct.ProductName = DirectCast(sender, Button).Text
SelectedProduct.ProductCost = DirectCast(ServicesBindingSource(0), DataRowView).DataView(0)(2)
ListBox1.Items.Add(SelectedProduct)
End Sub
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
For i As Integer = ListBox1.SelectedIndices.Count - 1 To 0 Step -1
ListBox1.Items.RemoveAt(ListBox1.SelectedIndices(i))
Next
End Sub
Private Sub TextBox1_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TextBox1.TextChanged
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim aValue As Decimal
For Each item As Product In ListBox1.Items
aValue += CDec(item.ProductCost)
Next
TextBox1.Text = aValue
End Sub
End Class
Cycle through each item using an integer as your count.
For i As Integer = 0 To ListBox1.Items.Count - 1
MsgBox(ListBox1.Items(i).ToString)
Next
Or you can add it to an integer/double value
For i As Integer = 0 To ListBox1.Items.Count - 1
MyInteger += Double.Parse.ListBox1.Items(i).ToString)
Next
MsgBox(MyInteger)
'Now the messagebox will show your total
EDIT:
Do not use ListBo1.Items.Item(i). Access directly through Listbox1.Items(i)

Adding 150,000 records to a listview without freezing UI

I have a listview loop that is adding 150,000 items to my listview. For testing purposes I moved this code to a background worker with delegates, but it still freezes up the UI. I am trying to find a solution so that it can add these items in the background while I do other stuff in the app. What solutions do you guys recommend?
this is what I am using
Public Class Form1
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
ListView1.Clear()
ListView1.BeginUpdate()
bw.WorkerReportsProgress = True
bw.RunWorkerAsync()
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
If bw.IsBusy Then bw.CancelAsync()
End Sub
Private Sub bw_DoWork(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles bw.DoWork
For x = 1 To 125000
Dim lvi As New ListViewItem("Item " & x)
If bw.CancellationPending Then
e.Cancel = True
Exit For
Else
bw.ReportProgress(0, lvi)
End If
Next
End Sub
Private Sub bw_ProgressChanged(ByVal sender As Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs) Handles bw.ProgressChanged
Try
Dim lvi As ListViewItem = DirectCast(e.UserState, ListViewItem)
Me.ListView1.Items.Add(lvi)
Catch ex As Exception
Throw New Exception(ex.Message)
End Try
End Sub
Private Sub bw_RunWorkerCompleted(ByVal sender As Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles bw.RunWorkerCompleted
ListView1.EndUpdate()
If Not e.Cancelled Then
Debug.Print("Done")
Else
Debug.Print("Cancelled")
End If
End Sub
End Class
Give this a try, it's a great example for what you would need... I also had a progress bar that shows the progress and such, see example image that is attached. Also I wasn't seeing any delegate that you need to perform such operation, mine has one that will be required. The reason is you are adding items to a control on the UI thread, in order to add items we need to know if an Invoke is required, if so we invoke otherwise we add the item to the control... Also I made the thread sleep, so it can take a break; this also prevents the UI from wanting to lock up here and there, now it's responsive with NO FREEZING.
Option Strict On
Option Explicit On
Public Class Form1
Delegate Sub SetListItem(ByVal lstItem As ListViewItem) 'Your delegate..
'Start the process...
Private Sub btnStartProcess_Click(sender As Object, e As EventArgs) Handles btnStartProcess.Click
lvItems.Clear()
bwList.RunWorkerAsync()
End Sub
Private Sub AddListItem(ByVal lstItem As ListViewItem)
If Me.lvItems.InvokeRequired Then 'Invoke if required...
Dim d As New SetListItem(AddressOf AddListItem) 'Your delegate...
Me.Invoke(d, New Object() {lstItem})
Else 'Otherwise, no invoke required...
Me.lvItems.Items.Add(lstItem)
End If
End Sub
Private Sub bwList_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles bwList.DoWork
Dim intCount As Integer = CInt(txtCount.Text)
Dim dblPercent As Integer = 100
Dim intComplete As Integer = 0
Dim li As ListViewItem = Nothing
For i As Integer = 1 To CInt(txtCount.Text)
If Not (bwList.CancellationPending) Then
li = New ListViewItem
li.Text = "Item " & i.ToString
AddListItem(li)
Threading.Thread.Sleep(1) 'Give the thread a very..very short break...
ElseIf (bwList.CancellationPending) Then
e.Cancel = True
Exit For
End If
intComplete = CInt(CSng(i) / CSng(intCount) * 100)
If intComplete < dblPercent Then
bwList.ReportProgress(intComplete)
End If
If li IsNot Nothing Then
li = Nothing
End If
Next
End Sub
Private Sub bwList_ProgressChanged(sender As Object, e As System.ComponentModel.ProgressChangedEventArgs) Handles bwList.ProgressChanged
pbList.Value = e.ProgressPercentage
End Sub
Private Sub bwList_RunWorkerCompleted(sender As Object, e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles bwList.RunWorkerCompleted
If pbList.Value < 100 Then pbList.Value = 100
MessageBox.Show(lvItems.Items.Count.ToString & " items were added!")
End Sub
Private Sub btnStopWork_Click(sender As Object, e As EventArgs) Handles btnStopWork.Click
bwList.CancelAsync()
End Sub
Private Sub btnRestart_Click(sender As Object, e As EventArgs) Handles btnRestart.Click
pbList.Value = 0
lvItems.Items.Clear()
txtCount.Text = String.Empty
End Sub
End Class
Screenshot in action...

how to delay text to speech code on textboxes visual basic 2010

Im trying to make my visual basic code speak multiple text boxes with a delay of 30 seconds between each textbox, so far i have:
Public Class Form1
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
If OpenFileDialog1.ShowDialog() = DialogResult.OK Then
End If
If My.Computer.FileSystem.FileExists(OpenFileDialog1.FileName) Then
Dim ioFile As New System.IO.StreamReader(OpenFileDialog1.FileName)
TextBox1.Text = ioFile.ReadLine()
TextBox2.Text = ioFile.ReadLine()
TextBox3.Text = ioFile.ReadLine()
TextBox4.Text = ioFile.ReadLine()
TextBox5.Text = ioFile.ReadLine()
TextBox6.Text = ioFile.ReadLine()
TextBox7.Text = ioFile.ReadLine()
TextBox8.Text = ioFile.ReadLine()
TextBox9.Text = ioFile.ReadLine()
TextBox10.Text = ioFile.ReadLine()
End If
End Sub
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
Dim SAPI
SAPI = CreateObject("SAPI.spvoice")
SAPI.Speak(TextBox1.Text)
End Sub
End Class
Basically i have 10 text boxes that have 10 words in them (loaded form a txt file) and i have a txt to speech code saying the first textbox but i want that text to speech code linked to button 2 to say all the textboxes with a 30 second delay between each textbox, how would i go about doing this?
For this to work you probably want a multithreaded application. However if you don't a quick and dirty way of making it would would be:
system.threading.thread.sleep(30000)
But then the UI would lock up. So you really want this running on a different thread. A timer is the easiest way to implement this. Just have the timer.tick value set to 30,000. When button 2 is pressed have it create an array with all the textbox strings in. The have a global variable (integer). Each time the timer is ticked it speaks the text in the array at the ndex of the global variable, then increment the global variable!
http://msdn.microsoft.com/en-us/library/system.timers.timer(v=vs.110).aspx
Here's an example using a BackgroundWorker() and an Enumerator built from the words in the TextBoxes:
Public Class Form1
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
If OpenFileDialog1.ShowDialog() = DialogResult.OK Then
Dim matches() As Control
Dim lines() As String = System.IO.File.ReadAllLines(OpenFileDialog1.FileName)
For i As Integer = 1 To 10
matches = Me.Controls.Find("TextBox" & i, True)
If matches.Length > 0 AndAlso TypeOf matches(0) Is TextBox Then
If i <= lines.Count Then
DirectCast(matches(0), TextBox).Text = lines(i - 1)
Else
DirectCast(matches(0), TextBox).Text = ""
End If
End If
Next
End If
End Sub
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
If Not BackgroundWorker1.IsBusy Then
Dim words As New List(Of String)
Dim matches() As Control
For i As Integer = 1 To 10
matches = Me.Controls.Find("TextBox" & i, True)
If matches.Length > 0 AndAlso TypeOf matches(0) Is TextBox Then
Dim TB As TextBox = DirectCast(matches(0), TextBox)
If TB.Text.Trim <> "" Then
words.Add(TB.Text.Trim)
End If
End If
Next
If words.Count > 0 Then
BackgroundWorker1.RunWorkerAsync(words.GetEnumerator)
End If
End If
End Sub
Private Sub BackgroundWorker1_DoWork(sender As System.Object, e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
Dim SAPI = CreateObject("SAPI.spvoice")
Dim wordsEnum As IEnumerator(Of String) = DirectCast(e.Argument, IEnumerator(Of String))
While wordsEnum.MoveNext
SAPI.Speak(wordsEnum.Current)
System.Threading.Thread.Sleep(TimeSpan.FromSeconds(30).TotalMilliseconds)
End While
End Sub
Private Sub BackgroundWorker1_RunWorkerCompleted(sender As Object, e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted
MessageBox.Show("Done!")
End Sub
End Class

How can I "compact" click events that use the same function?

I am creating a program that will allow a user to book seats in a theatre as a college project. It will feature a series of picture boxes that the user can click on to book a seat. The image in the picture box changes between the colour red and the colour green every time its pressed (if it is green, when it is clicked, it will become red etc.)
As for the function DetermineEnable, the value SeatNo represents the seat in the array enabled. This value is specific for each box (For seat A1, the seatno is 1). This value must remain the same, for the same box. The seatserial is just the name given to each picturebox (a1, a2, a3, a4, a5 etc).
I have only posted code for the first 5 seats, as this should give a general idea about what I'm asking.
What I'm asking is how can I "compact" all of the picturebox click events, So I only have to call the function "DetermineEnable" once or twice rather than 50+ times.
Many thanks!
' /// VISUAL AND INTERACTIVE DISPLAY
Sub DetermineEnable(ByVal SeatNo As Integer, ByVal SeatSerial As PictureBox)
If Enabled(SeatNo) = True Then
Enabled(SeatNo) = False
TotalCustomers = TotalCustomers - 1
ElseIf Enabled(SeatNo) = False Then
Enabled(SeatNo) = True
TotalCustomers = TotalCustomers + 1
End If
PictureLocation(SeatNo, SeatSerial)
UpdateEverything()
End Sub
Function PictureLocation(ByVal SeatNo As Integer, ByVal Picturebox As PictureBox) As String
If Enabled(SeatNo) = True Then
PictureLocation = "C:\Users\Wallace\Desktop\Theatre_Booking_System\enabled.png"
Else
PictureLocation = "C:\Users\Wallace\Desktop\Theatre_Booking_System\disabled.png"
End If
Picturebox.ImageLocation = PictureLocation
End Function
Private Sub a1_Click(sender As System.Object, e As System.EventArgs) Handles a1.Click
DetermineEnable(1, a1)
End Sub
Private Sub a2_Click(sender As System.Object, e As System.EventArgs) Handles a2.Click
DetermineEnable(2, a2)
End Sub
Private Sub a3_Click(sender As System.Object, e As System.EventArgs) Handles a3.Click
DetermineEnable(3, a3)
End Sub
Private Sub a4_Click(sender As System.Object, e As System.EventArgs) Handles a4.Click
DetermineEnable(4, a4)
End Sub
Private Sub a5_Click(sender As System.Object, e As System.EventArgs) Handles a5.Click
DetermineEnable(5, a5)
End Sub
Store the integer in the Tag property. Use the same sub to handle all the click events and cast the sender back to the PictureBox - which is the PictureBox that was clicked. a1.Tag = 1
Private Sub a1_Click(sender As System.Object, e As System.EventArgs) Handles a1.Click, a2,Click, a3.Click'etc...
Dim pb As PictureBox = DirectCast(sender, PictureBox)
DetermineEnable(Convert.ToInt32(pb.Tag), pb)
End Sub
Wire up the buttons in the Load() event, then extract the value from the name itself:
Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
Dim matches() As Control
For i As Integer = 1 To 50 ' <-- ajdust as necessary
matches = Me.Controls.Find("a" & i, True)
If matches.Length > 0 AndAlso TypeOf matches(0) Is PictureBox Then
Dim PB As PictureBox = DirectCast(matches(0), PictureBox)
AddHandler PB.Click, AddressOf pb_Click
End If
Next
End Sub
Private Sub pb_Click(sender As System.Object, e As System.EventArgs)
Dim PB As PictureBox = DirectCast(sender, PictureBox)
Dim value As Integer
If Integer.TryParse(PB.Name.TrimStart("a".ToCharArray), value) Then
DetermineEnable(value, PB)
End If
End Sub
Get rid of all the old hardcoded handlers for the PictureBoxes.
Something like this should work - put it in your Form_Load()...
Dim Pics = {a1, a2}
For i = 1 To Pics.Length
Dim Pic = Pics(i - 1)
AddHandler Pic.Click, Sub() DetermineEnable(i, Pic)
Next
If you don't want to define the list of controls manually, change
Dim Pics = {a1, a2}
to
Dim PicNamePattern As New System.Text.RegularExpressions.Regex("^a[0-9]*$")
Dim Pics = Me.Controls.Cast(Of Control).
Where(Function(x) PicNamePattern.IsMatch(x.Name))