Create a undo/redo textboxes algorithm in VB.Net - 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

Related

create function for sender object handler

how do i create a function for a sender as object click? I tried something, but it didn't work out.
Private Function functionName(ByVal sender As Object, e As EventArgs)
If sender.checked = True Then
For i As Integer = 2 To 14
If i <> 2 Then
Dim cbClubs = DirectCast(Controls.Item("cbBtt" & i & "detrefla"), CheckBox) 'Clubs
cbClubs.Checked = False
End If
Next
End If
End Function
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
functionName(cbBtt2detrefla, sender)
End Sub
Let's put some order in this code.
Private Function functionName(ByVal sender As Object, e As EventArgs)
'...
End Function
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
functionName(cbBtt2detrefla, sender)
End Sub
Why are you using e As EventArgs in functionName(...) declaration? It's never used, so u can delete it:
Private Function functionName(ByVal sender As Object)
In functionName you are evaluating sender.Checked (a tip: you can use If sender.Checked instead of If sender.Checked = True): why not to define sender as CheckBox, instead of Object?
Private Function functionName(ByVal sender As CheckBox)
Now, let's see the for Loop:
For i As Integer = 2 To 14
If i <> 2 Then
'...
End If
Next
You are evaluating i from 2 to 14, but you don't want to do anything if i = 2. Why not to start the for loop from i=3? It's faster and better.
For i As Integer = 3 To 14
'...
Next
Another thing: functionName() doesn't produce an output, so it should be a Sub, not a Function.
Now, your code is:
Private Sub functionName(ByVal sender As CheckBox)
If sender.Checked Then
For i As Integer = 3 To 14
'...
Next
End If
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
functionName(cbBtt2detrefla)
End Sub
Furthermore, if functionName is called only by Button1_Click and here it is only used with cbBtt2detrefla, you can avoid separating the two subs:
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
If cbBtt2detrefla.Checked Then
For i As Integer = 3 To 14
'...
Next
End If
End Sub
Last, but not least:
Dim cbClubs = DirectCast(Controls.Item("cbBtt" & i & "detrefla"), CheckBox) 'Clubs
cbClubs.Checked = False
This works only if cbBtt3detrefla and the others checkBoxes are directly on the form. If they are in a Panel, for example, you'll get a System.NullReferenceException. If you want to iterate on every control, you can do something like this.

Adding Conditions to the Listboxes from .csv files

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.

Shorten code vb.net

Is it possible to shorten these codes? If yes, how? Thanks for your answer guys.
Private Sub txtFirstName_GotFocus(sender As Object, e As EventArgs) Handles txtFirstName.GotFocus
lblFirstName.Visible = True
End Sub
Private Sub txtLastName_GotFocus(sender As Object, e As EventArgs) Handles txtLastName.GotFocus
lblLastName.Visible = True
End Sub
Private Sub txtMiddleName_GotFocus(sender As Object, e As EventArgs) Handles txtMiddleName.GotFocus
lblMiddleName.Visible = True
End Sub
Private Sub txtAddress_GotFocus(sender As Object, e As EventArgs) Handles txtAddress.GotFocus
lblAddress.Visible = True
End Sub
Private Sub txtContact_GotFocus(sender As Object, e As EventArgs) Handles txtContact.GotFocus
lblContact.Visible = True
End Sub
Since your labels and text boxes essentially have the same name (it's only the prefix that's different) you can:
Bind all GetFocus events to a single event handler.
Get the sender's name (sender is the control that raised the event), remove the txt prefix and replace it with lbl.
Look for a control by the new name (lbl...).
If found, make it visible.
In code it'd look like this:
Private Sub TextBoxes_GotFocus(sender As Object, e As EventArgs) Handles txtFirstName.GotFocus, txtLastName.GotFocus, txtMiddleName.GotFocus, txtAddress.GotFocus, txtContact.GotFocus
Const NamePrefix As String = "txt"
Const NewPrefix As String = "lbl"
Dim ctrl As Control = TryCast(sender, Control)
If ctrl IsNot Nothing AndAlso ctrl.Name.StartsWith(NamePrefix) Then 'Check if the sender's name starts with our prefix.
Dim NewName As String = NewPrefix & ctrl.Name.Remove(0, NamePrefix.Length) 'Remove the old prefix and replace it with the new one.
Dim Controls As Control() = Me.Controls.Find(NewName, True) 'Look for the control of our new name.
If Controls.Length > 0 Then 'Did we find one?
Controls(0).Visible = True 'Make it visible.
End If
End If
End Sub

NullReferenceException was unhandled VB.NET

I am trying to assign to an array a record that has to be split into more elements for search criteria reasons. For example, if criteria is set to First Name, then search for matching keyword in array element 0 because that's where first name will be placed after the currently selected record is Split().
Source for the search form:
Public Class frmSearch
Dim arrayCurrentRecord(6) As String
Private Sub btnCancel_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnCancel.Click
Me.DialogResult = DialogResult.Cancel
End Sub
Private Sub btnSearch_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSearch.Click
'fill array with list box items
Dim arraySearch(frmMain.numberOfRecords) As String
For i = 0 To frmMain.numberOfRecords - 1
arraySearch(i) = frmMain.lstListBox.Items(i)
Next i
If rbtnFirstName.Checked = True Then
For i = 0 To UBound(arraySearch)
arrayCurrentRecord = arraySearch(i).Split(" ")
If InStr(arrayCurrentRecord(0), txtSearch.Text) = True Then
lstSearch.Items.Add(arraySearch(i))
End If
Next i
MsgBox("search complete")
End If
End Sub
End Class
Changing For i = 0 To UBound(arraySearch) to
For i = 0 To UBound(arraySearch) - 1 fixed the issue, but it won't find anything just says that search was complete.
Changing line
If InStr(arrayCurrentRecord(0), txtSearch.Text) = True
to
If InStr(arrayCurrentRecord(0), txtSearch.Text)
resolved the problem.

vb.net array for slideshow button

Hey all, i am in the middle of trying to figure out how to go about doing this...
I have a form that i call like so:
call frmSlideShow.showWhat("1,4,8,9,11,22")
Each of the numbers represents a different image slide (slide1.png, slide4.png, etc..). The problem i am having is trying to create a "previous" and "next" button to flip through them all. Trying to figure out what number the user is on and going from there and seeing what numbers are still left from the list above that was sent, etc.
If anyone has an idea how i would go about doing that then that would be awesome! :)
UPDATE
here is the code..
Public Sub showWhat(ByVal theNumbers As String)
Dim theNums As String() = theNumbers.Split(New Char() {","c})
Dim theCurNum As String
For Each theCurNum In theNums
Debug.Print(theCurNum)
Next
End Sub
David
Put theNums string array one level up in your code along with an integer variable that keeps track of the current position in the array. Then your next button would check the upperbounds of theNums array to make sure you weren't on the last one. If you weren't, then it would increase the integer variable by one and then you could theNums(intTracker).
Public Class Form1
Dim theNums As String()
Dim intTracker As Integer = 0
Public Sub showWhat(ByVal theNumbers As String)
theNums = theNumbers.Split(New Char() {","c})
intTracker = 0
MsgBox("Currently showing " & theNums(intTracker))
If theNums.GetUpperBound(0) < 1 Then
btnNext.Enabled = False 'Only one number was passed, so disable the next button
End If
End Sub
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Call showWhat("1,2,3")
End Sub
Private Sub btnLast_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnLast.Click
btnNext.Enabled = True
intTracker -= 1
MsgBox("Now on " & theNums(intTracker))
If intTracker = 0 Then
btnLast.Enabled = False 'Disable the button because you're at the beginning
End If
End Sub
Private Sub btnNext_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnNext.Click
btnLast.Enabled = True
intTracker += 1
MsgBox("Now on " & theNums(intTracker))
If theNums.GetUpperBound(0) = intTracker Then
btnNext.Enabled = False 'On the last slide, so disable the next button
End If
End Sub
End Class