Highlight specific text while user is typing - vb.net

I am writing a code that highlight the duplicate words in a text. The code is working well when I add a button and the user have to press on the button to check for duplicates.
But I want to make an auto-checking code. I set my code in a subroutine that Handles RichTextBox.TextChanged. The problem is the code selects the target word and highlight it but the selection remains so when a new letter is typed, it clear what has been highlighted.
Here is my code:
Private Sub RichTextBox_TextChanged(sender As Object, e As EventArgs) Handles RichTextBox.TextChanged
Try
Call duplicate_check()
Catch ex As Exception
MessageBox.Show("error in RichTextBox.TextChanged")
End Try
End Sub
duplicate check function:
Private Sub duplicate_check()
Try
' read line by line and get input
Dim LineByLineInput() As String = RichTextBox.Lines
Dim selectionStart, selectionLength As Integer
Dim i, j As Integer
For lineNumber = 0 To UBound(LineByLineInput)
selectionStart = 0
selectionLength = 0
'get index of first char index in the current line
Dim count As Integer = lineNumber
While count <> 0
selectionStart += RichTextBox.Lines(count - 1).Length + 1
count -= 1
End While
' get line as string
Dim line As String = RichTextBox.Lines(lineNumber)
' split line into array of strings
Dim input() As String = line.Split(" ")
'check for duplicates
i = 0
For j = i + 1 To UBound(input)
If input(i) = input(j) Then 'compare each 2 consecutive words if they are the same
selectionStart += input(i).Length + 1
selectionLength = input(i).Length
RichTextBox.SelectionStart = selectionStart
RichTextBox.SelectionLength = selectionLength
RichTextBox.SelectionBackColor = Color.Yellow
Else
selectionStart += input(i).Length + 1
End If
i += 1
Next
Next
Catch ex As Exception
MessageBox.Show("error duplicate_check()")
End Try
End Sub

After your duplicate_check call, have you tried to set the selection of the RichTextBox back to the old position ?
See below :
Private Sub RichTextBox1_TextChanged(sender As Object, e As System.EventArgs) Handles RichTextBox1.TextChanged
Try
' Get current position
Dim cur_pos As Integer = Me.RichTextBox.SelectionStart
Call duplicate_check()
' Set back to old position
Me.RichTextBox.SelectionStart = cur_pos
' Unselect what your sub duplicate_check has selected
Me.RichTextBox1.SelectionLength = 0
Catch ex As Exception
MessageBox.Show("error in RichTextBox.TextChanged")
End Try
End Sub
If this solution is good for you, you should change your duplicate_check Sub to make this change and not in the RichTextBox1_TextChanged Sub

Related

getting System.InvalidOperationException: Listbox DataSource VB.net

This is the error I am getting
System.InvalidOperationException: 'List that this enumerator is bound to has been modified. An enumerator can only be used if the list does not change.'
I have a Listbox that is databound The list of items are stored days table the saved value is stored in a record table. The List is a Comma Separated List E.G: 1,2,3,4,5
Would equate to Items with values of 1 -5 being selected on load.
This is the save Routine which Works perfectly
Private Sub ListBox1_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ListBox1.Leave
Dim listboxItems As New List(Of String)
For Each row As DataRowView In ListBox1.SelectedItems
listboxItems.Add(row("IDNum"))
Next row
selectLoad = True
lblDays.Text = String.Join(",", listboxItems.ToArray())
End Sub
This is Routine Which is Throwing the error.
Private Sub BGWLoadData_RunWorkerCompleted(sender As Object, e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BGWLoadData.RunWorkerCompleted
Dim TextBoxStrings() As String = {""}
Try
Dim TempStr() As String = lblDays.Text.Split(",")
ReDim TextBoxStrings(TempStr.Count - 1)
TextBoxStrings = TempStr
Catch ex As Exception
End Try
Dim TextBoxDoubles(TextBoxStrings.Count - 1) As Double
For a As Integer = 0 To TextBoxStrings.Count - 1
Try
TextBoxDoubles(a) = TextBoxStrings(a)
Catch ex As Exception
TextBoxDoubles(a) = 0
End Try
Next
Do While DaysBound = False
Application.DoEvents()
Loop
ListBox1.SelectedItems.Clear()
Dim TempIndex As Integer = 0
For Each row As DataRowView In ListBox1.Items
For a As Integer = 0 To TextBoxDoubles.Count - 1
If row("IDNum") = TextBoxDoubles(a) Then
ListBox1.SetSelected(TempIndex, True)
End If
Next
TempIndex = TempIndex + 1
Next row
End Sub
What am I doing wrong or what can be done to make the code more efficient.
Edit:
Error Occurs at Next Row.
Also telling me I have done something wrong isn't helpful I know something is Wrong because I am getting errors. I am asking for is how to fix this with a code snippet or something.
This Has been Solved by Adding a second arrary
If selectLoad = False Then
' convert CSV of IDNums of selected items in listbox into string array
Dim TextBoxStrings() As String = {""}
Try
Dim TempStr() As String = lblDays.Text.Split(",")
ReDim TextBoxStrings(TempStr.Count - 1)
TextBoxStrings = TempStr
Catch ex As Exception
End Try
' convert string array to double array
Dim TextBoxDoubles(TextBoxStrings.Count - 1) As Double
For a As Integer = 0 To TextBoxStrings.Count - 1
Try
TextBoxDoubles(a) = TextBoxStrings(a)
Catch ex As Exception
TextBoxDoubles(a) = -1
End Try
Next
' load underlying IDNums into temporary array
Dim TempIndex As Integer = 0
Dim TempIDNums(ListBox1.Items.Count - 1) As Integer
For Each row As DataRowView In ListBox1.Items
TempIDNums(TempIndex) = row("IDNum")
TempIndex = TempIndex + 1
Next row
' if any of the underlying IDNums are found in the CSV, select that item in the listbox
ListBox1.SelectedItems.Clear()
For ListItemCounter As Integer = 0 To TempIDNums.Count - 1
For SelectedItemCounter As Integer = 0 To TextBoxDoubles.Count - 1
If TempIDNums(ListItemCounter) = TextBoxDoubles(SelectedItemCounter) Then
ListBox1.SetSelected(ListItemCounter, True)
End If
Next
Next
End If

How to debug a cast execption in vb.net?

I am getting a cast exception and I have re-written this code a large number of times. I am getting the exception on the following line:
If (CInt(hHurricaneYear) < CInt(_strYears(hAverage))) Then
And I am only getting results in the lblNumberOfHurricans. the other two labels are not showing any results. I thought I was getting it when the cast exception showed up.
Can anyone suggest how to get the results and stop the exception?
Here is what I have so far (well at least the last try).
Option Strict On
Public Class frmHurricaneStatistics
' Class level Private variables.
Public Shared _intSizeOfArray As Integer = 20
Private _strYears(_intSizeOfArray) As String
Private _intNumberOfHurricans(_intSizeOfArray) As Integer
Private Sub frmHurricaneStatistics_Load(sender As Object, e As EventArgs
) Handles MyBase.Load
' This load event reads the inventory text file and fills
' the ComboBox object with the Hurricane Statistics.
' Initialize an instace of the streamreader object and declare variables.
Dim objReader As IO.StreamReader
Dim strHurricaneStatistics As String = "Hurricanes.txt"
Dim intCount As Integer = 0
Dim intFill As Integer
Dim strFileError As String = "The file is not available. Please restart the
application when the file is available."
' Verify the Hurricane.txt file exists.
If IO.File.Exists(strHurricaneStatistics) Then
objReader = IO.File.OpenText(strHurricaneStatistics)
' Read the file line by line until the file is completed.
Do While objReader.Peek <> -1
_strYears(intCount) = objReader.ReadLine()
_intNumberOfHurricans(intCount) = Convert.ToInt32(objReader.ReadLine())
intCount += 1
Loop
objReader.Close()
' The ComboBox objext is filled with the Years for Hurricanes.
For intFill = 0 To (_strYears.Length - 1)
cmbYears.Items.Add(_strYears(intFill))
Next
Else
MsgBox(strFileError, , "Error")
Close()
' If ComboBox is filled then enable the Display Statistics button.
'btnDisplayStatistics.Enabled = True
End If
End Sub
Private Sub btnDisplayStatistics_Click(sender As Object, e As EventArgs
) Handles btnDisplayStatistics.Click
' This click event calls the sub procedures for the selected years and
' the number of hurricans in that year.
Dim intSelectedYear As Integer
Dim strMissingSelection As String = "Missing Selection"
Dim strSelectAYearError As String = "Please Select a Year"
' If the ComboBox object has a selection, Display Statistics.
If cmbYears.SelectedIndex >= 0 Then
intSelectedYear = cmbYears.SelectedIndex
Else
MsgBox(strSelectAYearError, , strMissingSelection)
End If
Private Sub btnDisplayStatistics_Click(sender As Object, e As EventArgs
) Handles btnDisplayStatistics.Click
' This click event calls the sub procedures for the selected years and
' the number of hurricans in that year.
Dim intSelectedYear As Integer
Dim strMissingSelection As String = "Missing Selection"
Dim strSelectAYearError As String = "Please Select a Year"
' If the ComboBox object has a selection, call the Display Statistics procedure.
If cmbYears.SelectedIndex >= 0 Then
intSelectedYear = cmbYears.SelectedIndex
Else
MsgBox(strSelectAYearError, , strMissingSelection)
End If
' This procedure MakeLabelsVisible Is called to display the labels
' And the results.
MakeLabelsVisible()
Dim hHurricaneAverage As Integer
Dim hHurricaneYear As Integer = 0
For hAverage As Integer = 0 To _strYears.Length - 1
If (CInt(hHurricaneYear) < CInt(_strYears(hAverage))) Then
hHurricaneYear = CInt(CType(CInt(_strYears(hAverage)), String))
End If
hHurricaneAverage = hHurricaneAverage + CInt((_strYears.ToString))
hHurricaneAverage = CInt(hHurricaneAverage / _strYears.Length)
Next
' Display the statistics for the Storm Average in the selected Year
' and the most active year within the range of year.
lblNumberOfHurricanes.Text = "The Number of Hurricanes in the Year " &
_strYears(intSelectedYear) & " is " & _intNumberOfHurricans(intSelectedYear).ToString() & "."
lblAvergeNumberHurricanes.Text = "The Average Number of Storms was " &
hHurricaneAverage & " Hurricanes."
Dim intSizeOfArray As Integer = Nothing
lblMostStorms.Text = "The Year "(CInt(_strYears(CInt(hHurricaneYear.ToString())) & "
Had The Most Storms Between " & (_strYears(0) & _strYears(20).ToString)))
End Sub
Option strict on
Your error lies in that you are trying to convert an entire string array into an integer:
hHurricaneAverage = hHurricaneAverage + CInt((_strYears.ToString))
You will need to call the index of _strYears:
hHurricaneAverage = hHurricaneAverage + CInt((_strYears(hAverage).ToString))
This will also explain why the other labels do not update, because hHurricanAverage never gets calculated.

Use streamreader to load data from text file into textboxes, code cannot find objStudent array

Option Strict On
Imports System.Text.RegularExpressions
Imports System.IO
Public Class StudentTestScores
Private Structure Student
Dim strStudentName As String
Dim dblTestScores() As Double
Dim dblAverage As Double
End Structure
Public Function GetDoubleTestScore(ByVal value As String) As Double
'Checks if the value is numeric and returns message if error is found
If IsNumeric(value) Then
Dim dblValue = CDbl(value)
'Check to make sure number is a positive and less or equal to 100
If dblValue >= 0 And dblValue <= 100 Then
Return dblValue
Else
Throw New Exception("The number needs to be between 0 and 100")
End If
Else
Throw New Exception("Please enter a number in the test score area.")
End If
End Function
Private Sub btnCalc_Click(sender As Object, e As EventArgs) Handles btnCalc.Click
'Creates variable and runs isValidName
Dim objStudent(6) As Student
If isValidName() = True Then
Try
' This initializes each of the test score arrays in a Student object
For i As Integer = 0 To 5
InitializeTestScores(objStudent(i))
Next
InitializeTestScores(objStudent(0))
'runs isNumeric function to txtStudentScores
objStudent(0).dblTestScores(0) = GetDoubleTestScore(txtStudent1Score1.Text)
objStudent(0).dblTestScores(1) = GetDoubleTestScore(txtStudent1Score2.Text)
objStudent(0).dblTestScores(2) = GetDoubleTestScore(txtStudent1Score3.Text)
objStudent(0).dblTestScores(3) = GetDoubleTestScore(txtStudent1Score4.Text)
objStudent(0).dblTestScores(4) = GetDoubleTestScore(txtStudent1Score5.Text)
objStudent(1).dblTestScores(0) = GetDoubleTestScore(txtStudent2Score1.Text)
objStudent(1).dblTestScores(1) = GetDoubleTestScore(txtStudent2Score2.Text)
objStudent(1).dblTestScores(2) = GetDoubleTestScore(txtStudent2Score3.Text)
objStudent(1).dblTestScores(3) = GetDoubleTestScore(txtStudent2Score4.Text)
objStudent(1).dblTestScores(4) = GetDoubleTestScore(txtStudent2Score5.Text)
objStudent(2).dblTestScores(0) = GetDoubleTestScore(txtStudent3Score1.Text)
objStudent(2).dblTestScores(1) = GetDoubleTestScore(txtStudent3Score2.Text)
objStudent(2).dblTestScores(2) = GetDoubleTestScore(txtStudent3Score3.Text)
objStudent(2).dblTestScores(3) = GetDoubleTestScore(txtStudent3Score4.Text)
objStudent(2).dblTestScores(4) = GetDoubleTestScore(txtStudent3Score5.Text)
objStudent(3).dblTestScores(0) = GetDoubleTestScore(txtStudent4Score1.Text)
objStudent(3).dblTestScores(1) = GetDoubleTestScore(txtStudent4Score2.Text)
objStudent(3).dblTestScores(2) = GetDoubleTestScore(txtStudent4Score3.Text)
objStudent(3).dblTestScores(3) = GetDoubleTestScore(txtStudent4Score4.Text)
objStudent(3).dblTestScores(4) = GetDoubleTestScore(txtStudent4Score5.Text)
objStudent(4).dblTestScores(0) = GetDoubleTestScore(txtStudent5Score1.Text)
objStudent(4).dblTestScores(1) = GetDoubleTestScore(txtStudent5Score2.Text)
objStudent(4).dblTestScores(2) = GetDoubleTestScore(txtStudent5Score3.Text)
objStudent(4).dblTestScores(3) = GetDoubleTestScore(txtStudent5Score4.Text)
objStudent(4).dblTestScores(4) = GetDoubleTestScore(txtStudent5Score5.Text)
objStudent(5).dblTestScores(0) = GetDoubleTestScore(txtStudent6Score1.Text)
objStudent(5).dblTestScores(1) = GetDoubleTestScore(txtStudent6Score2.Text)
objStudent(5).dblTestScores(2) = GetDoubleTestScore(txtStudent6Score3.Text)
objStudent(5).dblTestScores(3) = GetDoubleTestScore(txtStudent6Score4.Text)
objStudent(5).dblTestScores(4) = GetDoubleTestScore(txtStudent6Score5.Text)
' This loops through each Student structure object and calculates the average test score.
For i As Integer = 0 To 5
objStudent(i).dblAverage = CaculateStudentAverage(objStudent(i))
Next
objStudent(0).strStudentName = txtStudent1.Text
objStudent(1).strStudentName = txtStudent2.Text
objStudent(2).strStudentName = txtStudent3.Text
objStudent(3).strStudentName = txtStudent4.Text
objStudent(4).strStudentName = txtStudent5.Text
objStudent(5).strStudentName = txtStudent6.Text
lblAverageStudent1.Text = objStudent(0).dblAverage.ToString()
lblAverageStudent2.Text = objStudent(1).dblAverage.ToString()
lblAverageStudent3.Text = objStudent(2).dblAverage.ToString()
lblAverageStudent4.Text = objStudent(3).dblAverage.ToString()
lblAverageStudent5.Text = objStudent(4).dblAverage.ToString()
lblAverageStudent6.Text = objStudent(5).dblAverage.ToString()
'This creates the text file the program will write to
Dim StudentFile As System.IO.StreamWriter
Dim strFileName As String = "StudentTestScore.txt"
StudentFile = System.IO.File.AppendText(strFileName)
'Creates for loop that takes the 6 students
For i As Integer = 0 To 5
StudentFile.Write("Student Name: ")
StudentFile.Write(objStudent(i).strStudentName)
StudentFile.Write(" Student Test Scores: ")
'This creates a loop for the students and test scores
For intIndex2 As Integer = 0 To 4
StudentFile.Write(objStudent(i).dblTestScores(intIndex2).ToString())
If intIndex2 <> 4 Then
StudentFile.Write(", ")
End If
'Finally the average is ran using the objStudent (i)
Next
StudentFile.Write(" Average Score = ")
StudentFile.Write(objStudent(i).dblAverage.ToString())
StudentFile.WriteLine()
Next
'Closes the text file that was created
StudentFile.Close()
'Shows a message box that says the file was written to the text file and or modified
MessageBox.Show("Student Test Score file was created or modified.")
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
End If
End Sub
Private Sub InitializeTestScores(ByRef objStudent As Student) 'references objStudent object
' This takes the array dblTestScores and makes it a fixed array of size 6 since it could not be given a number in the structure
ReDim objStudent.dblTestScores(5)
End Sub
Private Function CaculateStudentAverage(ByVal objStudent As Student) As Double
' This loop loops through each value in dblTestScores and then just adds them to objstudent
For i As Integer = 0 To 4
objStudent.dblAverage += objStudent.dblTestScores(i)
Next
' This divides and then stores it back into the variable
objStudent.dblAverage /= 5
'Returns student average
Return objStudent.dblAverage
End Function
Private Sub LoadToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles LoadToolStripMenuItem.Click
' Create a new open file dialog
Dim MyFileDialog As New System.Windows.Forms.OpenFileDialog
' Configure the dialog to show only text files
' Set its title and set the filename field blank for the moment.
MyFileDialog.FileName = "StudentTestScore.txt"
' Show the dialog and see if the user pressed ok.
If MyFileDialog.ShowDialog() = Windows.Forms.DialogResult.OK Then
' Check to see if they selected a file and that it exists.
If File.Exists(MyFileDialog.FileName) Then
Dim strFile As String = MyFileDialog.FileName
Dim reader As StreamReader
Try
' Setup a file stream reader to read the text file.
reader = New StreamReader(New FileStream(strFile, FileMode.Open, FileAccess.Read))
' While there is data to be read, read each line into a rich edit box control.
Select
Case 0
txtStudent1.Text = Student.objStudent(0)
txtStudent1Score1.Text =
End Select
While reader.Peek > -1
txtStudent1.Text &= reader.ReadLine()
End While
' Close the file
reader.Close()
Catch ex As FileNotFoundException
' If the file was not found, tell the user.
MessageBox.Show("File was not found. Please try again.")
End Try
End If
End If
End Sub
End Class

How to search in listview

I am trying to create a Loop that will read through the information on my ListView through the SubItem to find the text that matches the text in my Textbox whenever I hit the search button and Focuses the listbox onto the matched text. Below is what I have but it keeps telling me that the value of string cannot be converted. I am also pretty sure that my numbers wont loop correctly but I am not really sure how to cause them to loop endlessly till end of statement.
Dim T As String
T = Lines.Text
For r As Integer = 0 to -1
For C As Integer = 0 to -1
If List.Items(r).SubItems(C).Text = Lines.Text Then
List.FocusedItem = T
End If
Next
Next
End Sub
I don't understand your code, but I do understand the question. Below is example code to search all rows and columns of a listview. Search is case insensitive and supports a "find next match" scenario. If a match or partial match is found in any column the row is selected. TextBox1 gets the text to find. FindBtn starts a new search.
Private SrchParameter As String = ""
Private NxtStrtRow As Integer = 0
Private Sub FindBtn_Click(sender As Object, e As EventArgs) Handles FindBtn.Click
If Not String.IsNullOrWhiteSpace(TextBox1.Text) Then
SrchParameter = TextBox1.Text
NxtStrtRow = 0
SearchListView()
End If
End Sub
Private Sub ListView1_KeyDown(sender As Object, e As KeyEventArgs) Handles ListView1.KeyDown
If e.KeyCode = Keys.F3 Then
SearchListView()
End If
End Sub
Private Sub SearchListView()
' selects the row containing data matching the text parameter
' sets NxtStrtRow (a form level variable) value for a "find next match" scenario (press F3 key)
If ListView1.Items.Count > 0 Then
If SrchParameter <> "" Then
Dim thisRow As Integer = -1
For x As Integer = NxtStrtRow To ListView1.Items.Count - 1 ' each row
For y As Integer = 0 To ListView1.Columns.Count - 1 ' each column
If InStr(1, ListView1.Items(x).SubItems(y).Text.ToLower, SrchParameter.ToLower) > 0 Then
thisRow = x
NxtStrtRow = x + 1
Exit For
End If
Next
If thisRow > -1 Then Exit For
Next
If thisRow = -1 Then
MsgBox("Not found.")
NxtStrtRow = 0
TextBox1.SelectAll()
TextBox1.Select()
Else
' select the row, ensure its visible and set focus into the listview
ListView1.Items(thisRow).Selected = True
ListView1.Items(thisRow).EnsureVisible()
ListView1.Select()
End If
End If
End If
End Sub
Instead of looping like that through the ListView, try using a For Each instead:
searchstring as String = "test1b"
ListView1.SelectedIndices.Clear()
For Each lvi As ListViewItem In ListView1.Items
For Each lvisub As ListViewItem.ListViewSubItem In lvi.SubItems
If lvisub.Text = searchstring Then
ListView1.SelectedIndices.Add(lvi.Index)
Exit For
End If
Next
Next
ListView1.Focus()
This will select every item which has a text match in a subitem.
Don't put this code in a form load handler, it won't give the focus to the listview and the selected items won't show. Use a Button click handler instead.
This is the easiest way to search in listview and combobox controls in vb net
dim i as integer = cb_name.findstring(tb_name.text) 'findstring will return index
if i = -1 then
msgbox("Not found")
else
msgbox("Item found")
end if

Index out-of-range error

I am getting an error when I execute this button event: here is my code:
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
Handles Button1.Click
Try
' get the details of the item
Dim R As Your_pharmacy.POSDS.ItemsRow = Button1.Tag
' next search for the barcode in the datagridview
Dim I As Integer
Dim ItemLoc As Integer = -1
For I = 0 To DGV1.Rows.Count - 1
If R.barcodeNumber = DGV1.Rows(I).Cells(0).Value Then
' item found
ItemLoc = I
Exit For
End If
Next
' if item is not found, add it
If ItemLoc = -1 Then
DGV1.Rows.Add(R.barcodeNumber, R.ItemName, R.BuyPrice, R.SellPrice, 1, R.SellPrice)
Else
' if item is already there increase its count
Dim ItemCount As Long = DGV1.Rows(ItemLoc).Cells(4).Value
ItemCount += 1
Dim NewPrice As Decimal = R.SellPrice * ItemCount
DGV1.Rows(ItemLoc).Cells(4).Value = ItemCount
DGV1.Rows(ItemLoc).Cells(5).Value = NewPrice
End If
' next clear textbox1 and set focus to it
TextBox1.Text = ""
TextBox1.Focus()
' compute the total for the recipt
Dim Sum As Decimal = 1
For I = 0 To DGV1.Rows.Count - 1
Sum += DGV1.Rows(I).Cells(5).Value 'here the error happens
Next
TextBox4.Text = Sum
Catch ex As Exception
MsgBox(ex.Message, MsgBoxStyle.Critical Or MsgBoxStyle.OkOnly, "Error")
End Try
End Sub
The error details:
error: index was out of range.must be non-negative and less than the
size of the collection. parameter name: index vb.net
DGV1 must have fewer cells than 5. When the error occurs, use a breakpoint and the debug watch window to see how many cells there are in DVG1(I). Maybe the first one is created with zero cells?