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();
我正在做一个基于 RichTextBox 的文本编辑器。它必须处理复杂的格式(BIU、彩色文本等)。问题是所有格式化工具都是基于 selection 的,例如我必须 select 一段文字,格式化它,select 接下来,等等
这需要时间,而且对用户可见。
有没有办法关闭RichTextBox重绘,然后格式化,再开启重绘?
或者可能有任何其他快速处理复杂格式的方法?
已找到决策并且正在运行。
用这个
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();