Выделение текста и изменение его цвета в строке RichTextBox

Добрый день. Я новичок в стеке переполнения в качестве плаката, но ссылался на него годами. Я изучал эту проблему около двух недель, и хотя я видел решения, которые близки, я все еще остаюсь с проблемой.

Я пишу графический интерфейс C#, который читает в файле кода сборки и выделяет различные текстовые элементы для дальнейшей обработки через другую программу. В моей форме есть RichTextBox, в котором отображается текст. В приведенном ниже примере я пытаюсь выделить текст в месте ';' до конца строки и измените цвет текста на красный. Вот код, который я использую.

Обратите внимание: файлы, считываемые программой, имеют непоследовательную длину, не все строки отформатированы одинаково, поэтому я не могу просто найти ';' и оперировать этим.

В другом сообщении участник дал метод расширения для AppendText, который я получил, чтобы работать отлично, за исключением того, что оригинальный текст все еще присутствует вместе с моим переформатированным текстом. Вот ссылка на этот сайт: Как использовать многоцветный в 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;
  }
}

Ниже приведен пример кода сборки из файла в исходном виде, весь текст черный:

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

когда rtb.GetFirstCharIndexOfCurrentLine() называется он возвращает действительный индекс RTB, и я представляю, что если я добавлю значение, возвращаемое line.LastIndexOf(';') Я тогда смогу просто выбрать текст выше, который выглядит как ; Assembly comments и включи его красным.

Что происходит, так это то, что вся линия становится красной.

Когда я использую метод AppendText выше, я получаю

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

Черный код - это тот же код, что и перекрашенный текст. В этом случае мне нужно знать, как очистить строку в RTB и / или переписать там текст. Все варианты, которые я пробовал, приводят к удалению этих строк.

Во всяком случае, я уверен, что это было долго, но я действительно озадачен здесь и был бы очень признателен за совет.

2 ответа

Решение

Надеюсь, я вас правильно понял.

Это зацикливается на каждой строке в richtextbox, определяет, какие строки являются комментариями сборки, а затем делает все красным после ";"

С циклом FOREACH по запросу

Чтобы использовать цикл foreach, вам просто нужно отслеживать индекс вручную, например так:

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

С петлей FOR

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

Пример красного выделенного richtext

Редактировать:

Перечитывая твой вопрос, я не понимаю, хотел ли ты сделать это; красный тоже.

Если вы удалите +1 из этой строки:

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

'Есть несколько ошибок, присущих методу rtb.select' Он выдает ошибки, если строка переносится, или дает сбой в строке "http" ... возможно, больше. (Я только что заметил, что цвета символов stackoverflow.com по умолчанию в моем приведенном выше коде не подходят для строк комментариев и других.)

Другие вопросы по тегам