【问题标题】:Selecting text and changing it's color on a line of a RichTextBox在 RichTextBox 的一行上选择文本并更改其颜色
【发布时间】:2021-10-03 13:28:29
【问题描述】:

下午好。我是作为海报堆栈溢出的新手,但多年来一直引用它。我已经研究了我的这个问题大约 2 周,虽然我已经看到了接近的解决方案,但我仍然遇到了一个问题。

我正在编写一个 C# gui,它读取一个汇编代码文件并突出显示不同的文本项,以便通过另一个程序进行进一步处理。我的表单有一个显示文本的 RichTextBox。在下面的情况下,我试图选择“;”位置处的文本,直到行尾并将文本更改为红色。这是我正在使用的代码。

请注意:程序读取的文件长度不一致,并非所有行的格式都相同,所以我不能简单地搜索';'并对其进行操作。

在另一篇文章中,一位成员给出了 AppendText 的扩展方法,除了原始文本和我重新格式化的文本仍然存在之外,我已经可以完美地工作了。这是该网站的链接: 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;
  }
}

以下是原始文件中的示例汇编代码,所有文本均为黑色:

;;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 中的行和/或覆盖那里的文本。我尝试过的所有选项都会删除这些行。

任何人,我敢肯定这很长,但我真的很难过,非常感谢您的建议。

【问题讨论】:

标签: c# visual-studio-2010 foreach richtextbox appendtext


【解决方案1】:

希望我理解正确。

这会遍历richtextbox 中的每一行,计算出哪些行是汇编 cmets,然后在“;”之后将所有内容变为红色

按要求使用 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;
    }
}

编辑:

重新阅读您的问题,我很困惑您是否想制作 ;也是红色的。

如果您确实从该行中删除了 +1:

int start = (richTextBox1.GetFirstCharIndexFromLine(i) + currentLine.LastIndexOf(";") + 1);

【讨论】:

  • 感谢您的帮助。只是因为我从另一个编码员那里接管了这个项目,有什么办法可以保留 foreach?
  • 更新了显示两个循环的答案。两者的工作方式相同,我只是觉得 FOR 循环的语法更清晰。希望它有所帮助:-)
  • 非常感谢您的帮助!我发现,当我执行richtextbox1.selectionlength = lengthrichtextbox1.selectionlength = 22(22 只是一个数字)同时观看它时,selectionlength 总是设置为零。知道为什么会这样吗?我禁用了 FIPS 是否与此有关?
  • 请原谅我的无知,但什么是 FIPS?我认为这与加密有关,我不确定这里是否相关。你是说这段代码不适合你吗?它应该适用于不以 ;; 开头的每一行。并在 a 的最后一个实例之后设置所有内容;变红。如果该行不包含 ;它不起作用,但您只在示例中提供了有限的文本,所以我无法使其更健壮。我认为您现在使用的示例包含的文本比您最初显示的要多得多?
  • Equalsk,代码有效。是的,FIPS 用于加密,但它已关闭,我不知道它是否还与其他任何东西混淆。说length = 24 在调试模式下,当我执行rtb1.selectionlength = length 而不是将selectionlength 属性设置为24 时,它总是设置为零。即使我硬编码一个数字而不是length,它仍然被设置为零。发生这种情况时会发生整条线变成红色的情况。这更清楚吗?是的,有更多的行而不是我举的简单的例子,但格式是一样的。
【解决方案2】:
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 字符颜色对于注释行和其他行不正确。)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-23
    • 2012-07-28
    • 2023-01-12
    • 1970-01-01
    • 1970-01-01
    • 2013-10-25
    相关资源
    最近更新 更多