2012-02-23 79 views
5

我有一个richTextBox我用来执行一些语法高亮。这是一个小编辑工具,所以我没有写一个自定义的语法高亮显示 - 而不是我使用Regex S和使用事件处理程序Application.Idle事件在检测到输入延迟的更新:RichTextBox BeginUpdate()EndUpdate()扩展方法不工作

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(汉斯帕桑特从来没有让我失望!):

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; 
} 

然而,这给了我在一个更新奇的行为;光标死亡/冻结,只显示奇怪的条纹(见下图)。

Odd Error Caused by RichTextBox Method Extension

我显然不能使用替代线程更新UI,所以我在做什么错在这里?

谢谢你的时间。

回答

7

尝试修改EndUpdate以后再调用Invalidate。控制器不知道它需要做一些更新,所以你需要告诉它:

public void EndUpdate() 
{ 
    SendMessage(this.Handle, WM_SETREDRAW, (IntPtr)1, IntPtr.Zero); 
    this.Invalidate(); 
} 
+0

这是薄荷!像魅力一样工作......一个小问题,你如何了解扩展方法及其细微之处? 'SendMessage(this.Handle,WM_SETREDRAW,(IntPtr)1,IntPtr.Zero);'不完全是标准的C#!?或者是? – MoonKnight 2012-02-23 19:42:49

+1

@Killercam'SendMessage'和Extensions是两个不同的东西。 'SendMessage'正在调用一个windows API函数。有关扩展,请参见[扩展方法(C#编程指南)](http://msdn.microsoft.com/zh-cn/library/bb383977.aspx)。 – LarsTech 2012-02-23 19:54:19

+0

感谢您的回复。我意识到两者是不同的。感谢您的链接和您的帮助,这是非常感谢。 – MoonKnight 2012-02-23 20:51:31