3

我有这个功能:

private void clearRichtextBox()
{
    richTextBox2.Clear();
    foreach (KeyValuePair<string, List<string>> kvp in LocalyKeyWords)
    {
        for (int i = 0; i < kvp.Value.Count(); i++)
        {
            richTextBox2.AppendText("Url: " + kvp.Key + " --- " + "Localy KeyWord: " + kvp.Value[i]+Environment.NewLine);
        }
    }   
}

它在哪里做Clear();它看起来像richTextBox 闪烁/闪烁几毫秒左右。有什么办法可以避免停止吗?

4

5 回答 5

3

我最近遇到了类似的问题。我选择的解决方案是向richtextbox 添加扩展方法。我喜欢这种方法,因为它干净、包含且易于重复使用。

这使得暂停重绘非常简单

richtextbox.SuspendDrawing();

并恢复

richtextbox.ResumeDrawing()

public static class RichTextBoxExtensions
{
    [DllImport("user32.dll")]
    private static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wp, IntPtr lp);
    private const int WM_SETREDRAW = 0x0b;

    public static void SuspendDrawing(this System.Windows.Forms.RichTextBox richTextBox)
    {
        SendMessage(richTextBox.Handle, WM_SETREDRAW, (IntPtr)0, IntPtr.Zero);
    }

    public static void ResumeDrawing(this System.Windows.Forms.RichTextBox richTextBox)
    {
        SendMessage(richTextBox.Handle, WM_SETREDRAW, (IntPtr)1, IntPtr.Zero);
        richTextBox.Invalidate();
    }
}

来源: https ://stackoverflow.com/a/487757/3442448

于 2014-03-26T15:39:44.223 回答
2

每当文本更改时,您无法避免将RichTextBox至少一次重绘排队的内在行为,但在您提供的代码片段中,您可以只设置带外准备文本而不是调用 clear. 这会将视觉活动的变化量降至最低,而无需更改其正常操作。此外,您似乎希望保持内容与您的 KeyValue 集的视图相同。

StringBuilder在将文本应用到 之前使用 a组合文本,如果有差异RichTextBox则分配属性。Text如果 的内容没有变化RichTextBox,则不会重绘所有内容,这是您看到的闪烁行为的根源。

private void clearRichtextBox()
{
    StringBuilder sb = new StringBuilder();

    foreach (KeyValuePair<string, List<string>> kvp in LocalyKeyWords)
    {
        for (int i = 0; i < kvp.Value.Count(); i++)
        {
            sb.AppendFormat("Url: {0} --- Localy KeyWord: {1}{2}", kvp.Key,kvp.Value[i],Environment.NewLine);
        }
    }

    string viewString = sb.ToString();
    if(viewString != richTextBox2.Text)
    {
         richTextBox2.Text = viewString;
    }
}
于 2012-10-14T22:40:25.460 回答
1

这就是它的工作原理。您可以尝试在表单上启用双缓冲:

this.DoubleBuffered = true;

另一种方法是继承 RichTextBox 控件并覆盖其 New() 方法SetStyle(),用于为控件本身启用双缓冲。

如何使用此方法:

public class MyRichTextBox : RichTextBox {

    protected override void New() {
        base.New();
        SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
    }
}

然后您需要执行以下步骤:

  1. 关闭设计器窗口
  2. 打开设计器文件
  3. 您需要将RichTextBox两次替换为MyRichTextBox,一次靠近声明文件的顶部,另一次靠近初始化文件的底部。
  4. 保存并重新打开设计器/测试
于 2012-10-14T22:22:28.950 回答
0

这也可能有帮助:

http://social.msdn.microsoft.com/Forums/en-US/winforms/thread/a6abf4e1-e502-4988-a239-a082afedf4a7

它使用 SendMessage 打开/关闭控件的重绘模式。

于 2012-10-14T22:28:38.620 回答
0

我还没有尝试过它是否也会闪烁,但您可以将 RTB 的值设置为空字符串。

richTextBox2.Text = "";
foreach (KeyValuePair<string, List<string>> kvp in LocalyKeyWords)
{
    for (int i = 0; i < kvp.Value.Count(); i++)
    {
        richTextBox2.AppendText("Url: " + kvp.Key + " --- " + "Localy KeyWord: " + kvp.Value[i]+Environment.NewLine);
    }
} 
于 2012-10-14T22:32:03.513 回答