C# 如何停止 RichTextBox 重绘?

C# how to stop RichTextBox redraw?

我正在做一个基于 RichTextBox 的文本编辑器。它必须处理复杂的格式(BIU、彩色文本等)。问题是所有格式化工具都是基于 selection 的,例如我必须 select 一段文字,格式化它,select 接下来,等等

这需要时间,而且对用户可见。

有没有办法关闭RichTextBox重绘,然后格式化,再开启重绘?

或者可能有任何其他快速处理复杂格式的方法?

已找到决策并且正在运行。

用这个

写了一个 wrap-class

Class本身:

  public class RichTextBoxRedrawHandler
{
    RichTextBox rtb;

    public RichTextBoxRedrawHandler (RichTextBox _rtb)
        {
        rtb = _rtb;
        }
    [DllImport("user32.dll")]
    private static extern IntPtr SendMessage(IntPtr hWnd, int wMsg, int wParam, ref Point lParam);

    [DllImport("user32.dll")]
    private static extern IntPtr SendMessage(IntPtr hWnd, int wMsg, int wParam, IntPtr lParam);

    const int WM_USER = 1024;
    const int WM_SETREDRAW = 11;
    const int EM_GETEVENTMASK = WM_USER + 59;
    const int EM_SETEVENTMASK = WM_USER + 69;
    const int EM_GETSCROLLPOS = WM_USER + 221;
    const int EM_SETSCROLLPOS = WM_USER + 222;

    private Point _ScrollPoint;
    private bool _Painting = true;
    private IntPtr _EventMask;
    private int _SuspendIndex = 0;
    private int _SuspendLength = 0;

    public void SuspendPainting()
    {
        if (_Painting)
        {
            _SuspendIndex = rtb.SelectionStart;
            _SuspendLength = rtb.SelectionLength;
            SendMessage(rtb.Handle, EM_GETSCROLLPOS, 0,  ref _ScrollPoint);
            SendMessage(rtb.Handle, WM_SETREDRAW, 0, IntPtr.Zero);
            _EventMask = SendMessage(rtb.Handle, EM_GETEVENTMASK, 0, IntPtr.Zero);
            _Painting = false;
        }
    }

    public void ResumePainting()
    {
        if (!_Painting)
        {
            rtb.Select(_SuspendIndex, _SuspendLength);
            SendMessage(rtb.Handle, EM_SETSCROLLPOS, 0, ref _ScrollPoint);
            SendMessage(rtb.Handle, EM_SETEVENTMASK, 0, _EventMask);
            SendMessage(rtb.Handle, WM_SETREDRAW, 1, IntPtr.Zero);
            _Painting = true;
            rtb.Invalidate();
        }

    }
}

用法:

RichTextBoxRedrawHandler rh = new RichTextBoxRedrawHandler(richTextBoxActually);
rh.SuspendPainting();
// do things with richTextBox
rh.ResumePainting();