我有一个 RichTextBox,我需要经常更新 Text 属性,但是当我这样做时,RichTextBox 会令人讨厌地“闪烁”,因为它会在整个方法调用中刷新所有内容。
我希望找到一种简单的方法来暂时抑制屏幕刷新,直到我的方法完成,但我在网上找到的唯一方法是覆盖 WndProc 方法。我采用了这种方法,但有一些困难和副作用,而且它也使调试变得更加困难。似乎必须有更好的方法来做到这一点。有人可以指出我更好的解决方案吗?
我有一个 RichTextBox,我需要经常更新 Text 属性,但是当我这样做时,RichTextBox 会令人讨厌地“闪烁”,因为它会在整个方法调用中刷新所有内容。
我希望找到一种简单的方法来暂时抑制屏幕刷新,直到我的方法完成,但我在网上找到的唯一方法是覆盖 WndProc 方法。我采用了这种方法,但有一些困难和副作用,而且它也使调试变得更加困难。似乎必须有更好的方法来做到这一点。有人可以指出我更好的解决方案吗?
这是完整且有效的示例:
private const int WM_USER = 0x0400;
private const int EM_SETEVENTMASK = (WM_USER + 69);
private const int WM_SETREDRAW = 0x0b;
private IntPtr OldEventMask;
[DllImport("user32.dll", CharSet=CharSet.Auto)]
private static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam);
public void BeginUpdate()
{
SendMessage(this.Handle, WM_SETREDRAW, IntPtr.Zero, IntPtr.Zero);
OldEventMask = (IntPtr)SendMessage(this.Handle, EM_SETEVENTMASK, IntPtr.Zero, IntPtr.Zero);
}
public void EndUpdate()
{
SendMessage(this.Handle, WM_SETREDRAW, (IntPtr)1, IntPtr.Zero);
SendMessage(this.Handle, EM_SETEVENTMASK, IntPtr.Zero, OldEventMask);
}
我问了最初的问题,最适合我的答案是 BoltBait 将 SendMessage() 与 WM_SETREDRAW 结合使用。与使用 WndProc 方法相比,它的副作用似乎更少,并且在我的应用程序中的执行速度是 LockWindowUpdate 的两倍。
在我扩展的 RichTextBox 类中,我刚刚添加了这两个方法,并且每当我需要在进行某些处理时停止重新绘制时,我都会调用它们。如果我想从 RichTextBox 类之外执行此操作,我认为只需将“this”替换为对 RichTextBox 实例的引用即可。
private void StopRepaint()
{
// Stop redrawing:
SendMessage(this.Handle, WM_SETREDRAW, 0, IntPtr.Zero);
// Stop sending of events:
eventMask = SendMessage(this.Handle, EM_GETEVENTMASK, 0, IntPtr.Zero);
}
private void StartRepaint()
{
// turn on events
SendMessage(this.Handle, EM_SETEVENTMASK, 0, eventMask);
// turn on redrawing
SendMessage(this.Handle, WM_SETREDRAW, 1, IntPtr.Zero);
// this forces a repaint, which for some reason is necessary in some cases.
this.Invalidate();
}
在这里找到:http: //bytes.com/forum/thread276845.html
我最终通过 SendMessage 发送 WM_SETREDRAW 以禁用然后重新启用,然后在完成更新后发送 Invalidate()。这似乎奏效了。
我从未尝试过这种方法。我已经编写了一个带有语法突出显示的 RTB 应用程序,并在 RTB 类中使用了以下内容:
protected override void WndProc(ref Message m)
{
if (m.Msg == paint)
{
if (!highlighting)
{
base.WndProc(ref m); // if we decided to paint this control, just call the RichTextBox WndProc
}
else
{
m.Result = IntPtr.Zero; // not painting, must set this to IntPtr.Zero if not painting otherwise serious problems.
}
}
else
{
base.WndProc(ref m); // message other than paint, just do what you normally do.
}
}
希望这可以帮助。
您可以将 Text 存储到一个字符串中,对字符串进行操作,然后在方法结束时将其存储回 Text 属性吗?
我建议看看LockWindowUpdate
[DllImport("user32.dll", EntryPoint="LockWindowUpdate", SetLastError=true,
ExactSpelling=true, CharSet=CharSet.Auto,
CallingConvention=CallingConvention.StdCall)]
试试这个:
myRichTextBox.SuspendLayout();
DoStuff();
myRichTextBox.ResumeLayout();