How can i check for a character after certain text within a listbox? - vb.net

How can i check for a character after other text within a listbox?
e.g
Listbox contents:
Key1: V
Key2: F
Key3: S
Key4: H
How do I find what comes after Key1-4:?
Key1-4 will always be the same however what comes after that will be user defined.
I figured out how to save checkboxes as theres only 2 values to choose from, although user defined textboxes is what im struggling with. (I have searched for solutions but none seemed to work for me)
Usage:
Form1_Load
If ListBox1.Items.Contains("Key1: " & UsersKey) Then
TextBox1.Text = UsersKey
End If
Which textbox1.text would then contain V / whatever the user defined.
I did try something that kind of worked:
Form1_Load
Dim UsersKey as string = "V"
If ListBox1.Items.Contains("Key1: " & UsersKey) Then
TextBox1.Text = UsersKey
End If
but i'm not sure how to add additional letters / numbers to "V", then output that specific number/letter to the textbox. (I have special characters blocked)
Reasoning I need this is because I have created a custom save settings which saves on exit and loads with form1 as the built in save settings doesn't have much customization.
e.g Can't choose save path, when filename is changed a new user.config is generated along with old settings lost.

Look at regular expressions for this.
Using the keys from your sample:
Dim keys As String = "VFSH"
Dim exp As New RegEx("Key[1-4]: ([" & keys& "])")
For Each item As String in ListBox1.Items
Dim result = exp.Match(item)
If result.Success Then
TextBox1.Text = result.Groups(1).Value
End If
Next
It's not clear to me how your ListBoxes work. If you might find, for example, "Key 2:" inside ListBox1 that you need to ignore, you will want to change the [1-4] part of the expression to be more specific.
Additionally, if you're just trying to exclude unicode or punctuation, you could also go with ranges:
Dim keys As String = "A-Za-z0-9"
If you are supporting a broader set of characters, there are some you must be careful with: ], \, ^, and - can all have special meanings inside of a regular expression character class.

You have multiple keys, I assume you have multiple textboxes to display the results?
Then something like this would work. Loop thru the total number of keys, inside that you loop thru the alphabet. When you find a match, output to the correct textbox:
Dim UsersKey As String
For i As Integer = 1 To 4
For Each c In "ABCDEFGHIJKLMNOPQRSTUVWXYZ".ToCharArray()
UsersKey = c
If ListBox1.Items.Contains("Key" & i & ": " & UsersKey) Then
Select Case i
Case 1
TextBox1.Text = UsersKey
Case 2
TextBox2.Text = UsersKey
Case 3
TextBox3.Text = UsersKey
Case 4
TextBox4.Text = UsersKey
End Select
Exit For 'match found so exit inner loop
End If
Next
Next
Also, you say your settings are lost when the filename is changed. I assume when the version changes? The Settings has an upgrade method to read from a previous version. If you add an UpgradeSettings boolean option and set it to True and then do this at the start of your app, it will load the settings from a previous version:
If My.Settings.UpgradeSettings = True Then
My.Settings.Upgrade()
My.Settings.Reload()
My.Settings.UpgradeSettings = False
My.Settings.Save()
End If
Updated Answer:
Instead of using a listtbox, read the settings file line by line and output the results to the correct textbox based on the key...something like this:
Dim settingsFile As String = "C:\settings.txt"
If IO.File.Exists(settingsFile) Then
For Each line As String In IO.File.ReadLines(settingsFile)
Dim params() As String = Split(line, ":")
If params.Length = 2 Then
params(0) = params(0).Trim
params(1) = params(1).Trim
Select Case params(0)
Case "Key1"
Textbox1.Text = params(1)
Case "Key2"
Textbox2.Text = params(1)
End Select
End If
Next line
End If

You can associate text box with a key via its Name or Tag property. Lets say you use Name. In this case TextBox2 is associated with key2. TextBox[N] <-> Key[N]
Using this principle the code will look like this [considering that your list item is string]
Sub Test()
If ListBox1.SelectedIndex = -1 Then Return
Dim data[] As String = DirectCast(ListBox1.SelectedItem, string).Split(new char(){":"})
Dim key As String = data(0).Substring(3)
Dim val As String = data(1).Trim()
' you can use one of the known techniques to get control on which your texbox sits.
' I omit this step and assume "Surface1" being a control on which your text boxes sit
DirectCast(
(From ctrl In Surface1.Controls
Where ctrl.Name = "TextBox" & key
Select ctrl).First()), TextBox).Text = val
End Sub
As you can see, using principle I just explained, you have little parsing and what is important, there is no growing Select case if, lets say, you get 20 text boxes. You can add as many text boxes and as many corresponding list items as you wish, the code need not change.

Related

How to remove and re-add a comma in a string?

I have a textbox on my form that when a button is clicked, it is populated with numbers that are separated by a comma. I have a delete button that will remove the numbers with the comma one at a time. My question is how would I go about re-adding the comma every time i hit the add button, again? I thought i could add the comma in the beginning in an if statement, but its adding two commas, every time I hit the add button, if I delete, then try to re- add.
here is what i have :
if textbox1.text = "" then
textbox1.text = textbox1.text & testNumber(combobox.selecteditem) & ","
else
textbox1.text = "," & textbox1.text & testnumber(combox.selecteditem)
end if
The contents of the textbox should only be a view of a more appropriate underlying data structure. For example, you might have a List(Of Integer) or Queue(Of Integer) as a member of your form. When you add or remove an item you first update the collection, then you set the text. For example:
Add:
MyList.Add(nextNumber)
textbox1.text = String.Join(","c, MyList)
Remove:
MyList.RemoveAt(MyList.Count - 1);
textbox1.text = String.Join(","c, MyList)
Do this even if they want the ability to update the textbox directly. It's just in this case you must also be able to validate and parse the contents of the textbox to recreate the list.
First of all, storing numbers in a comma delimited string is pretty strange requirement. I'd suggest to store numbers in a proper data type, such as: List(Of Integer).
Assuming that testnumber function returns integer...
'define at the top of Form's module:
Private myNumbers As List(Of Integer) = New List(Of Integer)()
'copy-paste below method to the form's module
Private Function GetCommaSeparatedNumbers() As String
Return String.Join(",", myNumbers)
End Function
'finally:
'to add number
myNumbers.Add(testnumber(combox.selecteditem))
'to remove number
myNumbers.Remove(testnumber(combox.selecteditem))
'to display numbers
Me.textbox1.Text = GetCommaSeparatedNumbers()
If you would like to check out if number already exists on the list, use:
If myNumbers.Contains(testnumber(combox.selecteditem)) Then
'display warning
Else
'add number
End If
Good luck!
Your code is initial testing textbox1.Text = "" and then, if that is true, it is then doing textbox1.Text = textbox1.Text & testNumber(combobox.SelectedItem) & ",", but since textbox1.Text is "" this is the equivalent of:
textbox1.Text = "" & testNumber(combobox.SelectedItem) & ","
That really means you are adding a comma when you only have one number.
This is what you should be doing:
if textbox1.Text = "" then
textbox1.Text = testNumber(combobox.SelectedItem)
else
textbox1.Text = textbox1.Text & "," & testnumber(combox.SelectedItem)
end if
To add a number, I'd do it with this line:
TextBox1.AppendText(If(TextBox1.TextLength = 0, "", ",") & testNumber(ComboBox.SelectedItem))
Are numbers being deleted from the beginning or end?...or is a "selected" number from anywhere in the list being deleted?

Wildcard Search character in vb.net

I am wanting to make a wildcard search character (ex. Binary%) so when they click search it finds all the files with the word Binary in the filename and loads them into a list box. My current code is below.
Private Sub _test_TextChanged(sender As Object, e As TextChangedEventArgs) Handles _test.TextChanged
For x As Integer = 0 To _listbox.Items.Count - 1
If _listbox.Items(x).ToString = _test.Text$ Then
_listbox.SelectedIndex = x
Return
End If
Next
End Sub
Any help is welcome!
Thank you!
-Kyvex
What you are asking doesn't really match your code.
... "when they click search it finds all the files" ...
But you have a TextChanged event handler of a TextBox (not a Button)
..."with the word Binary in the filename and loads them into a list box"
But you select only the first item which matches the filter of items already in a ListBox
To get your code to do what it seems to want to do, simply use the Like operator and add the wildcard character (*) after the TextBox.Text
For x As Integer = 0 To _listBox.Items.Count - 1
If _listBox.Items(x).ToString Like _test.Text & "*" Then
_listBox.SelectedIndex = x
Return
End If
Next
Now you can select the first item in the listbox which matches the filter
If you have a multi-select ListBox, you can use this
If _test.Text = "" Then Exit Sub
_listBox.SelectionMode = SelectionMode.MultiSimple
For x As Integer = 0 To _listBox.Items.Count - 1
_listBox.SetSelected(x, _listBox.Items(x).ToString Like _test.Text & "*")
Next
(the filter logic is the same as the first example)
And you can make it case-insensitive
_listBox.SetSelected(x, _listBox.Items(x).ToString().ToUpper() Like _test.Text.ToUpper() & "*")

How to find and delete matching words in two different text files in VB?

Its a wordy question, but basically I want to have VB check textfile1 for matching words in textfile2, and then delete all instances of similar words in textfile2 and output the results as results.txt.
Outputting results shouldn't be too difficult, but i'm unsure on where to proceed when it comes to recognizing similar wordage. Also, would it be possible to set up a whitelist (there's going to be one word repeated over and over - which I don't want deleted).
This is my open file / read file dialogue which I use for both prompts, and both are displayed visually in a textbox.
Sub Maplist()
If txtFile.ShowDialog() = System.Windows.Forms.DialogResult.OK Then
Dim sr As New System.IO.StreamReader(txtFile.FileName)
tbx1.Text = sr.ReadToEnd
sr.Close()
End If
Thanks for any help!
Edit:
A sample of the first text file looks like this:
map_01, 200/250
map_03, 358/450
map_06, 528/2000
The second file looks like:
map_01
map_02
map_03
map_04
map_05
map_06
Basically the second file is the "master list'. I want the program to recognize a matching word between both files (for instance, the 01 in map_01) and then delete the entry from the master list. When I was talking about whitelisting I was concerned that it would match a word like"map" and delete everything in the master list. I didn't wanted it to delete the whole word just because it matched "map"
You have to make an array of words from both the TextFile and compare those. I did it for you here:
Private Sub Button2_Click(sender As System.Object, e As System.EventArgs) Handles Button2.Click
'make array of words from both the files
Dim text1Array() As String = TextBox1.Text.Split(" ")
Dim text2Array() As String = TextBox2.Text.Split(" ")
Dim NewText As String
NewText = TextBox2.Text
'loop through all the words in first array
For i = 0 To text1Array.Length - 1
'loop through all the words in second array
For j = 0 To text2Array.Length - 1
'match the words
If text1Array(i) = text2Array(j) Then
'replace the found word with an empty character
NewText = NewText.Replace(text2Array(j), String.Empty)
'delete double space
NewText = NewText.Replace(" ", " ")
End If
Next
Next
'save it into third textbox
TextBox3.Text = NewText
End Sub
I checked it like this:
Textbox1 contained :
one two three four five six seven eight nine ten eleven twelve
TextBox2 contained :
one subaz three sarma five loves six coding eight ten all the twelve time
After clicking the button, TextBox3 contained:
subaz sarma loves coding all the time
This works perfectly fine.
Now, about the whitelist, let's say you don't want to remove "five" even if it's matched. Do this:
Dim WhiteListWord As String = "five"
And change the condition as :
If text1Array(i) = text2Array(j) And text1Array(i) <> WhiteListWord Then
New output in the textbox3 will be :
subaz sarma five loves coding all the time

How do I display the result of a loop on a new line in a text box?

Basically, how do I write a new line in a text box, keeping the existing information as well.
If I have for loop,
For i As Integer = 1 To 10
Dim result = i
i = i + 1
textbox1.text = result
Next
This will display '10' in the textbox. I want it to be like:
1
2
3
4
...
First, your TextBox must allow multiple lines. This is a property of the textbox control that you can set from the designer or from the code. You may want to ensure that a scroll bar is there to scroll in case the height is not large enough.
If you want to set the properties from code, use this code in the Load event of the form.
' Set the Multiline property to true.
textBox1.Multiline = True
' Add vertical scroll bars to the TextBox control.
textBox1.ScrollBars = ScrollBars.Vertical
' Change the height of the textbox so that it could accomodate the lines
TextBox1.Height = 120
Now, your approach had a major problem in this line:
textbox1.text = result
The way you coded it, every new value of i, would overwrite the old value. What you want to do is to first construct a string, then send the entire string to the TextBox control. This is not required had you been using Console.WriteLine method.
Method 1
Dim s as string
s=""
For i As Integer = 1 To 10
s = s & Environment.Newline & i.ToString() 'we use Environment.NewLine to force new line
Next i
textbox1.text = s
Method 2
.NET offers a class to handle strings better than the way we did before. It won't matter in your case but it is the efficient way to handle concatenation when volume is large and/or performance matters
Dim s as new System.Text.StringBuilder() 'Initialize stringbuilder instance
For i As Integer = 1 To 10
s.AppendLine (i.ToString()) 'We use stringbuilder to concat. and inser line feed
Next i
textbox1.text = s.ToString()
Note: If you want double spacing then you need to add a linefeed (using & ) to both of the above methods.
Something like this should work:
For i As Integer = 1 To 10
if i = 1 then
textbox1.text = i
else
textbox1.text &= vbcrlf & i
end if
Next
For i = 1 To 10
textbox1.AppendText(vbNewLine & i)
Next

visual basic search text for string, display results with propercase

...databox.text (from example code below) contains a large list of combined words(domain names) previously populated in the program. There is 1 per each line. In this example, it initially looks like:
thepeople.com
truehistory.com
workhorse.com
whatever.com
neverchange.com
...
The following code below saves the text inside databox to tlistfiltered.txt and then searches tlistfiltered.txt to retrieve all lines that contain any of the items in the list "arr()", and then populates listview(lv) with the results. This works just fine, but the results look like:
thepeople.com
truehistory.com
neverchange.com
...
but what I need is the "found string" (from arr()list to be Proper case so the result would be:
thePeople.com
trueHistory.com
neverChange.com
Here is the code....
Dim s As String = databox.Text
File.WriteAllText(dloc & "tlistfiltered.txt", s)
databox.Clear()
Dim text2() As String = System.IO.File.ReadAllLines(dloc & "tlistfiltered.txt")
Dim arr() As String = {"people", "history", "change"}
For index1 = 0 To arr.GetUpperBound(0)
Dim YesLines() As String = Array.FindAll(text2, Function(str As String)
Return str.Contains(arr(index1))
End Function).ToArray
databox.Visible = True
For index2 = 0 To YesLines.GetUpperBound(0)
Dim match As String = (YesLines(index2)) & vbCrLf
databox.AppendText(match)
Next
Next
s = databox.Text
File.WriteAllText(dloc & "tlistfilteredfinal.txt", s)
databox.Clear()
domains = (From line In File.ReadAllLines(dloc & "tlistfilteredfinal.txt") Select New ListViewItem(line.Split)).ToArray
lv.Items.Clear()
My.Computer.FileSystem.DeleteFile(dloc & "tlistfiltered.txt")
My.Computer.FileSystem.DeleteFile(dloc & "tlistfilteredfinal.txt")
BackgroundWorker1.RunWorkerAsync()
End Sub
Is there a way to do this on the fly? I have tried StrConv etc, but it will only convert the entire line to proper case. I only want the "found" word contained within the line to be converted....
edit:
after seeing #soohoonigan 's answer, i edited
databox.Visible = True
For index2 = 0 To YesLines.GetUpperBound(0)
Dim match As String = (YesLines(index2)) & vbCrLf
databox.AppendText(match)
Next
Next
to this:
databox.Visible = True
For index2 = 0 To YesLines.GetUpperBound(0)
Dim match As String = (YesLines(index2)) & vbCrLf
Dim myTI As System.Globalization.TextInfo = New System.Globalization.CultureInfo("en-US", False).TextInfo
If match.Contains(arr(index1)) Then
match = match.Replace(arr(index1), myTI.ToTitleCase(arr(index1)))
'StrConv(match, vbProperCase)
databox.AppendText(match)
End If
Next
and got the desired result!
Public Class Form1
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim test As String = "thepeople.com"
Dim search As String = "people"
Dim myTI As System.Globalization.TextInfo = New System.Globalization.CultureInfo("en-US", False).TextInfo
If test.Contains(search) Then
test = test.Replace(search, myTI.ToTitleCase(search))
MsgBox(test)
End If
Me.Close()
End Sub
End Class
I'm not sure to understand the need for using files for intermediate steps and deleting them at the end for example.
First step: getting the lines of the input
That can be done by using the Lines property of databox (which I suspect to be a TextBox or RichTextBox ; if it's not the case we can still use a Split on the Text property)
Dim lines = databox.Lines ' or databox.Text.Split({Environment.NewLine}, StringSplitOptions.RemoveEmptyEntries)
Second step: we want to filter those lines to keep only the ones containing the searched texts
For this there are several way, a simple one would be to use a Linq query to get the job done
Third step: transforming the result of the filter replacing the searched text by it's capitalized form
So we continue the started query and add a projection (or mapping) to do the transformation.
We need to use TextInfo.ToTitleCase for that.
' See soohoonigan answer if you need a different culture than the current one
Dim textInfo = System.Globalization.CultureInfo.CurrentCulture.TextInfo
Dim query = From word in arr
From line in lines
Where line.Contains(word)
Let transformed = line.Replace(word, textInfo.ToTitleCase(word))
select transformed
' We could omit the Let and do the Replace directly in the Select Clause