2012-02-23 85 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