简体   繁体   中英

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 ; 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.

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;
    }
}

红色突出显示的富文本示例

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM