Selecting text and changing it's color on a line of a RichTextBox

3.8k Views Asked by At

Good Afternoon. I am new to stack overflow as a poster but have referenced it for years. I have been researching this problem of mine for about 2 weeks and while I've seen solutions that are close I still am left with an issue.

I am writing a C# gui that reads in an assembly code file and highlights different text items for further processing via another program. My form has a RichTextBox that the text is displayed in. In the case below I am trying to select the text at the location of the ‘;’ until the end of the line and change the text to color red. Here is the code that I am using.

Please note: The files that are read in by the program are of inconsistent length, not all lines are formatted the same so I cannot simply search for the ';' and operate on that.

On another post a member has given an extension method for AppendText which I have gotten to work perfectly except for the original text is still present along with my reformatted text. Here is the link to that site: How to use multi color in richtextbox

// Loop that it all runs in
Foreach (var line in inArray)
{   

  // getting the index of the ‘;’ assembly comments
  int cmntIndex = line.LastIndexOf(';');

  // getting the index of where I am in the rtb at this time.  
  int rtbIndex = rtb.GetFirstCharIndexOfCurrentLine();

  // just making sure I have a valid index
  if (cmntIndex != -1)
  {
    // using rtb.select to only select the desired 
    // text but for some reason I get it all    
    rtb.Select(cmntIndex + rtbIndex, rtb.SelectionLength);
    rtb.SelectionColor = Color.Red;
  }
}

Below is the sample assembly code from a file in it's original form all the text is black:

;;TAG SOMETHING, SOMEONE START                          
    ASSEMBLY CODE       ; Assembly comments
    ASSEMBLY CODE       ; Assembly comments
    ASSEMBLY CODE       ; Assembly comments
;;TAG SOMETHING, SOMEONE FINISH

When rtb.GetFirstCharIndexOfCurrentLine() is called it returns a valid index of the RTB and I imagine that if I add the value returned by line.LastIndexOf(';') I will then be able to just select the text above that looks like ; Assembly comments and turn it red.

What does happen is that the entire line turns red.

When I use the AppendText method above I get

ASSEMBLY CODE (this is black) ; Assembly comments (this is red) (the rest is black) ASSEMBLY CODE ; Assembly comments

The black code is the exact same code as the recolored text. In this case I need to know how to clear the line in the RTB and/or overwrite the text there. All the options that I have tried result in deletion of those lines.

Anywho, I'm sure that was lengthy but I'm really stumped here and would greatly appreciate advice.

2

There are 2 best solutions below

7
Equalsk On BEST ANSWER

I hope I've understood you correctly.

This loops over each line in the richtextbox, works out which lines are the assembly comments, then makes everything red after the ";"

With FOREACH loop as requested

To use a foreach loop you simply need to keep track of the index manually like so:

// Index
int index = 0;

// Loop over each line
foreach (string line in richTextBox1.Lines)
{
    // Ignore the non-assembly lines
    if (line.Substring(0, 2) != ";;")
    {
        // Start position
        int start = (richTextBox1.GetFirstCharIndexFromLine(index) + line.LastIndexOf(";") + 1);

        // Length
        int length = line.Substring(line.LastIndexOf(";"), (line.Length - (line.LastIndexOf(";")))).Length;

        // Make the selection
        richTextBox1.SelectionStart = start;
        richTextBox1.SelectionLength = length;

        // Change the colour
        richTextBox1.SelectionColor = Color.Red;
    }

    // Increase index
    index++;
}

With FOR loop

// Loop over each line
for(int i = 0; i < richTextBox1.Lines.Count(); i++)
{
    // Current line text
    string currentLine = richTextBox1.Lines[i];

    // Ignore the non-assembly lines
    if (currentLine.Substring(0, 2) != ";;")
    {
        // Start position
        int start = (richTextBox1.GetFirstCharIndexFromLine(i) + currentLine.LastIndexOf(";") + 1);

        // Length
        int length = currentLine.Substring(currentLine.LastIndexOf(";"), (currentLine.Length - (currentLine.LastIndexOf(";")))).Length;

        // Make the selection
        richTextBox1.SelectionStart = start;
        richTextBox1.SelectionLength = length;

        // Change the colour
        richTextBox1.SelectionColor = Color.Red;
    }
}

Example of red highlighted richtext

Edit:

Re-reading your question I'm confused as to whether you wanted to make the ; red as well.

If you do remove the +1 from this line:

int start = (richTextBox1.GetFirstCharIndexFromLine(i) + currentLine.LastIndexOf(";") + 1);
0
YaoChen Aan On
Private Sub RichTextBox1_Click(sender As Object, e As EventArgs) Handles RichTextBox1.Click
    Dim MyInt1 As Integer
    Dim MyInt2 As Integer
    ' Reset your RTB back color to white at each click
    RichTextBox1.SelectionBackColor = Color.White
    ' Define the nth first character number of the line you clicked
    MyInt1 = RichTextBox1.GetFirstCharIndexOfCurrentLine()
    ' use that nth to find the line number in the RTB
    MyInt2 = RichTextBox1.GetLineFromCharIndex(MyInt1)
    'Select the line using an array property of RTB (RichTextBox1.Lines())
    RichTextBox1.Select(MyInt1, RichTextBox1.Lines(MyInt2).Length)
    ' This line would be for font color change : RichTextBox1.SelectionColor = Color.Maroon
    ' This one changes back color :
    RichTextBox1.SelectionBackColor = Color.Yellow
End Sub

' There are a few bugs inherent to the rtb.select method ' It bugs if a line wraps, or fails on an "http" line... probably more. (I just noticed the default stackoverflow.com character colors on my above code are not correct for comment lines and others.)