在 C# 中为 RichTextBox 中所有出现的位置着色的更快方法

发布于 2024-09-25 21:06:04 字数 1067 浏览 5 评论 0原文

我有一个 RichTextBox,指定的搜索字符串大约出现了 1000 多次。

我使用以下函数为所有出现的情况着色:

public void ColorAll(string s)
{
    rtbxContent.BeginUpdate();

    int start = 0, current = 0;
    RichTextBoxFinds options = RichTextBoxFinds.MatchCase;
    start = rtbxContent.Find(s, start, options);
    while (start >= 0)
    {
        rtbxContent.SelectionStart  = start;
        rtbxContent.SelectionLength = s.Length;
        rtbxContent.SelectionColor     = Color.Red;
        rtbxContent.SelectionBackColor = Color.Yellow;

        current = start + s.Length;
        if (current < rtbxContent.TextLength)
            start = rtbxContent.Find(s, current, options);
        else
            break;
    }

    rtbxContent.EndUpdate();
}

但我发现它非常慢。

但是,如果我对另一个单词的所有出现次数进行着色,而该单词在同一文本中出现次数较少,我发现它的速度非常快。

所以我猜缓慢是来自(这两行可能会涉及UI刷新):

    rtbxContent.SelectionColor     = Color.Red;
    rtbxContent.SelectionBackColor = Color.Yellow;

是否有一种更快的方法来完成相同的工作,例如,我在内存中进行着色,然后一次性显示结果?

我说清楚了吗?

谢谢。

I have a RichTextBox, and there are about more than 1000 occurrences of a specified search string.

I use the following function to color all the occurrences:

public void ColorAll(string s)
{
    rtbxContent.BeginUpdate();

    int start = 0, current = 0;
    RichTextBoxFinds options = RichTextBoxFinds.MatchCase;
    start = rtbxContent.Find(s, start, options);
    while (start >= 0)
    {
        rtbxContent.SelectionStart  = start;
        rtbxContent.SelectionLength = s.Length;
        rtbxContent.SelectionColor     = Color.Red;
        rtbxContent.SelectionBackColor = Color.Yellow;

        current = start + s.Length;
        if (current < rtbxContent.TextLength)
            start = rtbxContent.Find(s, current, options);
        else
            break;
    }

    rtbxContent.EndUpdate();
}

But I found it's very slow.

However, if I color all the occurrences of another word, which has less number of occurrences in the same text, I found it's very fast.

So I guess the slowness is from (these two line might get UI refresh involved):

    rtbxContent.SelectionColor     = Color.Red;
    rtbxContent.SelectionBackColor = Color.Yellow;

Is there a faster way of doing the same job, such as, I do the coloring in the memory, and then I display the result at one-go?

Do I make myself clear?

Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

剩一世无双 2024-10-02 21:06:04

有一个更快的方法。

使用正则表达式查找匹配项,然后在 Richtextbox 中突出显示

    if (this.tBoxFind.Text.Length > 0)
    {
        try
        {
               this.richTBox.SuspendLayout();
               this.Cursor = Cursors.WaitCursor;

           string s = this.richTBox.Text;
           System.Text.RegularExpressions.MatchCollection mColl = System.Text.RegularExpressions.Regex.Matches(s, this.tBoxFind.Text);

           foreach (System.Text.RegularExpressions.Match g in mColl)
           {
                  this.richTBox.SelectionColor = Color.White;
                  this.richTBox.SelectionBackColor = Color.Blue;

                  this.richTBox.Select(g.Index, g.Length);
           }
   }
   finally
   {
         this.richTBox.ResumeLayout();
         this.Cursor = Cursors.Default;
   }
}

There is a faster way.

Use regex to find the matches then highlight in the richtextbox

    if (this.tBoxFind.Text.Length > 0)
    {
        try
        {
               this.richTBox.SuspendLayout();
               this.Cursor = Cursors.WaitCursor;

           string s = this.richTBox.Text;
           System.Text.RegularExpressions.MatchCollection mColl = System.Text.RegularExpressions.Regex.Matches(s, this.tBoxFind.Text);

           foreach (System.Text.RegularExpressions.Match g in mColl)
           {
                  this.richTBox.SelectionColor = Color.White;
                  this.richTBox.SelectionBackColor = Color.Blue;

                  this.richTBox.Select(g.Index, g.Length);
           }
   }
   finally
   {
         this.richTBox.ResumeLayout();
         this.Cursor = Cursors.Default;
   }
}
jJeQQOZ5 2024-10-02 21:06:04

所花费的时间与发生的次数成正比。

使用时间最多的可能是“查找”。您可以将此行: 替换

    start = rtbxContent.Find(s, start + s.Length, options); 

为:

    start = rtbxContent.Find(s, current, options);

由于您已计算 current 等于 start + s.Length

您还可以将 s.Length 存储为变量,因此您无需每次都计算字符串中的所有字符。 rtbxContent.TextLength 也是如此。

The amount of time it takes is directly proportional to the number of occurances.

It is probably the Find that is using the most time. You could replace this line:

    start = rtbxContent.Find(s, start + s.Length, options); 

with this:

    start = rtbxContent.Find(s, current, options);

Since you have computed current to equal start + s.Length

You could also store s.Length is a variable so you do not need to count all the characters in a string each time. The same goes for rtbxContent.TextLength.

我一直都在从未离去 2024-10-02 21:06:04

字符串搜索是线性的。如果您发现Find方法很慢,也许您可​​以使用第三方工具来为您进行搜索。您所需要的只是字符串中模式的索引。

也许这会对您有所帮助。您应该计算差异并使用更快的那个。

The string search is linear. If you find Find method to be slow, maybe you can use third party tool to do the searching for you. All you need is index of the pattern in a string.

Maybe this will help you. You should time the difference and use the faster one.

请止步禁区 2024-10-02 21:06:04

你是在正确的轨道上,Winforms 缓慢的 RichTextBox 实现是罪魁祸首。您还很好地使用了 BeginUpdate 和 EndUpdate 方法(我猜您是从此处获取这些方法的?)。但可惜,这还不够。

有几种解决方案:

1:尝试将 RTF 直接写入文本框。这是一种相当混乱、复杂的格式,但幸运的是,我在此处创建了一个答案,它可以解决问题。

2:这个评价很高的外部项目看起来也很值得一看:http://www.codeproject.com/Articles/161871/Fast-Colored-TextBox-for-syntax-highlighting

You're on the right track that Winforms' slow RichTextBox implementation is to blame. You also did well to use the BeginUpdate and EndUpdate methods (I'm guessing you took those from here?). But alas, that isn't enough.

A couple of solutions:

1: Try writing the RTF directly to the textbox. This is a fairly messy, complicated format, but luckily, I have created an answer here which will do the trick.

2: This highly rated external project also looks well worth a look: http://www.codeproject.com/Articles/161871/Fast-Colored-TextBox-for-syntax-highlighting

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文