I used following code to color lines.
For line As Integer = 1 To RichTextBox1.Lines.Count() - 1
If RichTextBox1.Lines(line).StartsWith("You:") Then
RichTextBox1.Select(RichTextBox1.GetFirstCharIndexFromLine(line), RichTextBox1.Lines(line).Length)
RichTextBox1.SelectionColor = Color.Black
Else
RichTextBox1.Select(RichTextBox1.GetFirstCharIndexFromLine(line), RichTextBox1.Lines(line).Length)
RichTextBox1.SelectionColor = System.Drawing.ColorTranslator.FromHtml(color1)
End If
Next
It works fine when each line is actually one line long.
However if one message is longer it breaks whole coloring below the line:
On the picture the last line should be colored black, but second was colored instead.
How can I fix this?
When WordWrap is True, the Lines() array will return every line as you see it in the control, so a "wrapped" line is getting treated as a new line.
Try splitting on the line feed character and calculate the positions yourself:
Dim lines() As String = RichTextBox1.Text.Split(vbLf)
Dim startIndex As Integer = 0
For i As Integer = 0 To lines.Length - 1
RichTextBox1.Select(startIndex, lines(i).Length)
If lines(i).StartsWith("You:") Then
RichTextBox1.SelectionColor = Color.Red
Else
RichTextBox1.SelectionColor = Color.Green
End If
startIndex += lines(i).Length + vbLf.Length
Next
If you set RichTextBox1.WordWrap to False it works as expected.
Related
I have a multiline text box and I want to get line number that specific word in it.
I tried this:
For Each line As String In TextBox1.Lines
If line = "50" Then
Label2.Text = 'Number Of line
End If
Next
But I don't know how to get line number that "50" in it and show it in label2.
how can i do that?
Try using a counter:
Dim iLineCount As Integer = 0
For Each line As String In TextBox1.Lines
iLineCount += 1
If line = "50" Then
Label2.Text = iLineCount.ToString()
End If
Next
Use a For-loop instead of a For Each:
Dim lines = TextBox1.Lines
For i As Int32 = 0 To lines.Length - 1
If lines(i) = "50" Then Label2.Text = (i + 1).ToString()
Next
I'm storing the TextBox.Lines String() in a variable because there's some overhead if you use this property often.
Or try this:
Dim lines = TextBox1.Lines
Label2.Text = Array.IndexOf(lines, "50").ToString()
That will show the (zero based) index of first line to contain "50". Or -1 if no matching lines found.
I have a list view that contains four columns. I want to check the fourth column and see what the length of string.
note that there are two lines in some rows of this column as shown in the photo below.
each line on these rows shoud be counted separatly. if one line is more than 38 charecters, the row background will change can i do that?
thank you all
like this:
this is my cod for listview that contain one column:
For i = 0 To ListView1.Items.Count - 1
ListView1.Items(i).Selected = True
If ListView1.Items(i).Text.Count > 38 Then
ListView1.SelectedItems(i).BackColor = Color.FromArgb(216, 141, 111)
Else
End If
Next i
If you mean that the HTML break tag <br /> in the fourth column is there as a line break identifier and you want to change the subitem's background color if the length of any line is greater than 38, then you can write:
For Each lvi As ListViewItem In ListView1.Items
If lvi.SubItems.Count > 2 Then
lvi.UseItemStyleForSubItems = False
If lvi.SubItems(3).Text.
Split({"<br/>", "<br />"}, StringSplitOptions.RemoveEmptyEntries).
Any(Function(line) line.Length > 38) Then
lvi.SubItems(3).BackColor = Color.FromArgb(216, 141, 111)
Else
lvi.SubItems(3).BackColor = SystemColors.Window
End If
End If
Next
If you need instead to change the background color of the ListViewItem:
For Each lvi As ListViewItem In ListView1.Items
If lvi.SubItems.Count > 2 Then
lvi.UseItemStyleForSubItems = True 'The default.
If lvi.SubItems(3).Text.
Split({"<br/>", "<br />"}, StringSplitOptions.RemoveEmptyEntries).
Any(Function(line) line.Length > 38) Then
lvi.BackColor = Color.FromArgb(216, 141, 111)
Else
lvi.BackColor = SystemColors.Window
End If
End If
Next
Without the Linq code. Sometimes easier to follow. I know Linq is cool but it is not any faster.
Private Sub FindLongLines()
For Each itm As ListViewItem In ListView1.Items
Dim TurnBrown As Boolean
Dim lines = itm.SubItems(3).Text.Split({"<br/>"}, StringSplitOptions.RemoveEmptyEntries)
For Each line In lines
If line.Length > 38 Then
TurnBrown = True
Exit For 'as soon as any line is found longer than 38 further checking is unnessary.
End If
Next
If TurnBrown Then
itm.SubItems(3).BackColor = Color.Brown
End If
Next
End Sub
All my below code remove all blank lines from TextBox.
But I want the cursor pointed line to get removed when clicked on button.
'First method
TextBox2.Lines = TextBox2.Lines.Where(Function(l) Not String.IsNullOrWhiteSpace(l)).ToArray()
Dim count = TextBox2.Lines.Length
'Second method
Dim tmp() As String = TextBox2.Text.Split(CChar(vbNewLine))
TextBox2.Clear()
For Each line As String In tmp
If line.Length > 1 Then
TextBox2.AppendText(line & vbNewLine)
End If
Next
'Third method
Dim SearchIn = Me.TextBox2.Text
Dim sb As StringBuilder = New StringBuilder(SearchIn)
Me.TextBox2.Text = sb.Replace(vbCrLf + vbCrLf, vbCrLf).ToString
'Fourth method
TextBox2.Text = Regex.Replace(TextBox2.Text, "(?<Text>.*)(?:[\r\n]?(?:\r\n)?)", "${Text} ") + "/n"
TextBox2.Text = Replace(TextBox2.Text, vbCrLf & vbCrLf, vbCrLf)
To remove a line of text from a TextBoxBase derived control (TextBox, RichTextBox), you first have to identify the correct line.
You can't use the .Lines property if the Text is wrapped, because it will return the line number relative to the unwrapped text.
You can get the current wrapped line with GetLineFromCharIndex(). The Integer parameter is the current caret position, referenced by the SelectionStart property.
The first character index of this line is retured by GetFirstCharIndexFromLine().
Then, find the current line lenght, identifying the first line feed. Add the lenght of the line feed symbol(s) to include them in the computed lenght.
Note that TextBox controls use Environment.Newline to generate a line feed ("\r\n"), while RichTextBox controls use only a line feed ("\n").
This will remove any line where the caret is currently positioned:
(If you just want to allow blank lines to be removed, check whether the line lenght is < 3).
Dim CurrentPosition As Integer = TextBox2.SelectionStart
Dim CurrentLine As Integer = TextBox2.GetLineFromCharIndex(CurrentPosition)
Dim LineFirstChar As Integer = TextBox2.GetFirstCharIndexFromLine(CurrentLine)
Dim LineLenght As Integer = TextBox2.Text.
IndexOf(Environment.NewLine, LineFirstChar) - LineFirstChar +
Environment.NewLine.Length
If LineLenght <= 0 Then Return
TextBox2.Select(LineFirstChar, LineLenght)
TextBox2.SelectedText = TextBox2.SelectedText.Remove(0)
TextBox2.SelectionLength = 0
TextBox2.SelectionStart = If(CurrentPosition < TextBox2.Text.Length, LineFirstChar, TextBox2.Text.Length)
TextBox2.Focus()
This will instead remove the whole paragraph that contains the caret:
Dim CurrentPosition As Integer = TextBox2.SelectionStart
Dim ParagraphFirstIndex As Integer = TextBox2.Text.
LastIndexOf(Environment.NewLine, CurrentPosition) +
Environment.NewLine.Length
Dim LineFeedPosition As Integer = TextBox2.Text.IndexOf(Environment.NewLine, ParagraphFirstIndex)
LineFeedPosition = If(LineFeedPosition > -1, LineFeedPosition + Environment.NewLine.Length, TextBox2.Text.Length)
Dim LineLenght As Integer = LineFeedPosition - ParagraphFirstIndex
If LineLenght <= 0 Then Return
TextBox2.Select(ParagraphFirstIndex, LineLenght)
TextBox2.SelectedText = TextBox2.SelectedText.Remove(0)
TextBox2.SelectionLength = 0
TextBox2.SelectionStart = If((CurrentPosition < TextBox2.Text.Length), ParagraphFirstIndex, TextBox2.Text.Length)
TextBox2.Focus()
So I made a chat in vb.net (using FTP server) and I want to color each name from my chat
so the file with messages is something like the following:
#2George: HI
#2George: Hi geoo
and using RichTextBox1 textchanged event I add:
For Each line In RichTextBox1.Lines
If Not line Is Nothing Then
If line.ToString.Trim.Contains("#2") Then
Dim s$ = line.Trim
RichTextBox1.Select(s.IndexOf("#") + 1, s.IndexOf(":", s.IndexOf("#")) - s.IndexOf("#") - 1)
MsgBox(RichTextBox1.SelectedText)
RichTextBox1.SelectionColor = Color.DeepSkyBlue
End If
End If
Next
the first name (George) changed his color but the second one didn't.
Any ideas why this is happening?
The main problem is that your IndexOf calculations are using the index of the current line, but you are not translating that index to where that line is being used in the RichTextBox. That is, your second line of #2George: Hi geoo is finding an index of 0 for the # sign, but index 0 in the RichTextBox is referring to the line #2George: HI, so you keep redrawing the first line every time.
To fix the immediate problem:
For i As Integer = 0 To RichTextBox1.Lines.Count - 1
Dim startIndex As Integer = RichTextBox1.Text.IndexOf("#", _
RichTextBox1.GetFirstCharIndexFromLine(i))
If startIndex > -1 Then
Dim endIndex As Integer = RichTextBox1.Text.IndexOf(":", startIndex)
If endIndex > -1 Then
RichTextBox1.Select(startIndex, endIndex - startIndex)
RichTextBox1.SelectionColor = Color.DeepSkyBlue
End If
End If
Next
The next problem is that doing this in the TextChanged event re-draws all the lines all the time. That won't scale too well. Consider drawing the text before you add it to the control by using a preformatted RTF line. Something like this:
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
AddRTFLine("#2George", "Hi")
AddRTFLine("#2George", "Hi geoo")
End Sub
Private Sub AddRTFLine(userName As String, userMessage As String)
Using box As New RichTextBox
box.SelectionColor = Color.DeepSkyBlue
box.AppendText(userName)
box.SelectionColor = Color.Black
box.AppendText(": " & userMessage)
box.AppendText(Environment.NewLine)
box.SelectAll()
RichTextBox1.Select(RichTextBox1.TextLength, 0)
RichTextBox1.SelectedRtf = box.SelectedRtf
End Using
End Sub
I'm building a program that gets the publisher of the book by scanning its title page and using OCR … since publishers are always at the bottom of the title page I'm thinking that a detecting lines that are separated by space is a solution but I don't know how to test for that. Here is my code:
Dim builder As New StringBuilder()
Dim reader As New StringReader(txtOCR.Text)
Dim iCounter As Integer = 0
While True
Dim line As String = reader.ReadLine()
If line Is Nothing Then Exit While
'i want to put the condition here
End While
txtPublisher.Text = builder.ToString()
Do you mean empty lines? Then you can do this:
Dim bEmpty As Boolean
And then inside the loop:
If line.Trim().Length = 0 Then
bEmpty = True
Else
If bEmpty Then
'...
End If
bEmpty = False
End If
Why not do the following: from the bottom, go up until you find the first non-empty line (no idea how the OCR works … maybe the bottom-most line is always non-empty, in which case this is redundant). In the next step, go up until the first empty line. The text in the middle is the publisher.
You don’t need the StringReader for that:
Dim lines As String() = txtOCR.Text.Split(Environment.NewLine)
Dim bottom As Integer = lines.Length - 1
' Find bottom-most non-empty line.
Do While String.IsNullOrWhitespace(lines(bottom))
bottom -= 1
Loop
' Find empty line above that
Dim top As Integer = bottom - 1
Do Until String.IsNullOrWhitespace(lines(top))
top -= 1
Loop
Dim publisherSubset As New String(bottom - top)()
Array.Copy(lines, top + 1, publisherSubset, 0, bottom - top)
Dim publisher As String = String.Join(Environment.NewLine, publisherSubset)
But to be honest I don’t think this is a particularly good approach. It’s inflexible and doesn’t cope well with unexpected formatting. I’d instead use a regular expression to describe what the publisher string (and its context) looks like. And maybe even that isn’t enough and you have to put some thought into describing the whole page to extrapolate which of the bits is the publisher.
Assuming the publisher is always on the last line and always comes after an empty line. Then perhaps the following?
Dim Lines as New List(Of String)
Dim currentLine as String = ""
Dim previousLine as String = ""
Using reader As StreamReader = New StreamReader(txtOCR.Txt)
currentLine = reader.ReadLine
If String.IsNullOrWhiteSpace(previousLine) then lines.Add(currentLine)
previousLine = currentLine
End Using
txtPublisher.Text = lines.LastOrDefault()
To ignore if the previous line is blank/empty:
Dim Lines as New List(Of String)
Using reader As StreamReader = New StreamReader(txtOCR.Txt)
lines.Add(reader.ReadLine)
End Using
txtPublisher.Text = lines.LastOrDefault()