我有一个我用来执行语法高亮的richTextBox。这是一个小编辑工具,因此我没有编写自定义语法高亮显示 - 而是使用Regex
并使用Application.Idle
事件的事件处理程序检测输入延迟时更新:
Application.Idle += new EventHandler(Application_Idle);
在事件处理程序中,我检查文本框是否处于非活动状态:
private void Application_Idle(object sender, EventArgs e)
{
// Get time since last syntax update.
double timeRtb1 = DateTime.Now.Subtract(_lastChangeRtb1).TotalMilliseconds;
// If required highlight syntax.
if (timeRtb1 > MINIMUM_UPDATE_DELAY)
{
HighlightSyntax(ref richTextBox1);
_lastChangeRtb1 = DateTime.MaxValue;
}
}
但即使对于相对较小的亮点,RichTextBox
也会大量闪烁,并且没有richTextBox.BeginUpdate()/EndUpdate()
方法。为了解决这个问题,我发现this answer to a similar dilemma by Hans Passant(Hans Passant从未让我失望!):
using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;
class MyRichTextBox : RichTextBox
{
public void BeginUpdate()
{
SendMessage(this.Handle, WM_SETREDRAW, (IntPtr)0, IntPtr.Zero);
}
public void EndUpdate()
{
SendMessage(this.Handle, WM_SETREDRAW, (IntPtr)1, IntPtr.Zero);
}
[DllImport("user32.dll")]
private static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wp, IntPtr lp);
private const int WM_SETREDRAW = 0x0b;
}
然而,这在更新时给了我奇怪的行为;光标死亡/冻结,只显示奇怪的条纹(见下图)。
我显然无法使用替代线程来更新UI,所以我在这里做错了什么?
感谢您的时间。
答案 0 :(得分:7)
尝试修改EndUpdate
以便之后再调用Invalidate。控件不知道需要进行一些更新,所以你需要告诉它:
public void EndUpdate()
{
SendMessage(this.Handle, WM_SETREDRAW, (IntPtr)1, IntPtr.Zero);
this.Invalidate();
}