Search code examples
c#visual-studio-2010foreachrichtextboxappendtext

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


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.


Solution

  • 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);