2017-02-21 59 views
1

類似的問題已經被問到(例如,here),但是我沒有找到我的具體情況的答案。我正在構建一個基於DevExpress控件的自定義控件,該控件依次基於標準TextBox,並且我有一個閃爍的問題,這似乎是由於基本的TextBox組件,它試圖更新選擇。防止在文本框中選擇文本

沒有解釋我的自定義控件的所有細節,重現你只需要放置一個TextBox一個Form內,然後使用此代碼的問題:

public partial class Form1 : Form { 
    public Form1() { 
     InitializeComponent(); 
     textBox1.MouseMove += TextBox1_MouseMove; 
    } 

    private void TextBox1_MouseMove(object sender, MouseEventArgs e) { 
     (sender as TextBox).Text = DateTime.Now.Ticks.ToString(); 
    } 
} 

如果你啓動它,你點擊TextBox然後您將光標向右移動,您會注意到閃爍問題(請參閱視頻here)。對於我的自定義控件,我需要避免這種閃爍。我一定會使用TextBox(所以沒有RichTextBox)。任何想法?

+0

您想避免選擇嗎?還是要允許選擇,但文本更改時不應閃爍? –

+0

我試過你的例子,點擊後沒有閃爍。它應該是其他事件重寫,你可以分享其他事件 –

+0

來自MSDN'當你爲MouseMove處理程序編寫代碼時要小心。當用戶與應用程序或具有處理程序的特定對象區域進行交互時,MouseMove經常會發生。 MouseMove處理程序中的任何計算密集或圖形密集的代碼都可能會在鼠標指針(或手寫筆指針)繪製的方式和應用程序通常的行爲方式上引入明顯的延遲。「我想說這是因爲它在鼠標移動過程中多次更新。 –

回答

1

該解決方案已經通過重寫WndProc和攔截WM_SETFOCUS消息在由禮Aghaei同時提供。請參閱here

0

取決於什麼ü想做的事有幾種解決方案:

如果你想防止選擇這將是:

 private void TextBox1_MouseMove(object sender, MouseEventArgs e) 
    { 
     (sender as TextBox).Text = DateTime.Now.Ticks.ToString(); 
     (sender as TextBox).SelectionLength = 0; 
    } 

或者選擇所有:

 private void TextBox1_MouseMove(object sender, MouseEventArgs e) 
    { 
     (sender as TextBox).Text = DateTime.Now.Ticks.ToString(); 
     (sender as TextBox).SelectAll(); 
    } 

除此之外,你還可以指定選擇的條件,例如:

 private void TextBox1_MouseMove(object sender, MouseEventArgs e) 
    { 
     (sender as TextBox).Text = DateTime.Now.Ticks.ToString(); 
     if (MouseButtons == MouseButtons.Left) (sender as TextBox).SelectAll(); 
     else (sender as TextBox).SelectionLength = 0; 
    } 

但是,只要你想選擇文本,你總是會得到一些閃爍,因爲一個正常的文本框沒有可能使用像BeginEdit和EndEdit的東西,所以它會改變文本,然後選擇它。

+0

我想避免選擇我的問題所述,通過這樣做我想避免閃爍。您提供的第一個解決方案('(發件人爲TextBox).SelectionLength = 0;')不會阻止閃爍 –

0

看着視頻,它看起來像你的文本框不必要地調用WM_ERASEBKGND。爲了解決這個問題,你可以繼承這個文本框類並攔截這些消息。下面是示例代碼應該做的伎倆(未經測試)免責聲明:我已經使用此技術的其他WinForm控件的類型閃爍顯示在您的視頻但不是TextBox。如果它適合你,請告訴我。祝你好運!

// textbox no flicker 
public partial class TexttBoxNF : TextBox 
{ 
    public TexttBoxNF() 
    { 
    } 

    public TexttBoxNF(IContainer container) 
    { 
     container.Add(this); 

     InitializeComponent(); 

     //Activate double buffering 
     this.SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.AllPaintingInWmPaint, true); 

     //Enable the OnNotifyMessage event so we get a chance to filter out 
     // Windows messages before they get to the form's WndProc 
     this.SetStyle(ControlStyles.EnableNotifyMessage, true); 
    } 

    //http://stackoverflow.com/questions/442817/c-sharp-flickering-listview-on-update 
    protected override void OnNotifyMessage(Message m) 
    { 
     //Filter out the WM_ERASEBKGND message 
     if (m.Msg != 0x14) 
     { 
      base.OnNotifyMessage(m); 
     } 
    } 
} 
+0

我嘗試了您的解決方案,但不起作用 –

+0

@MauroGanswer - 您可以嘗試的是在OnNotifyMessage函數中添加一些代碼將顯示或更好,記錄進入的消息。感興趣的消息將在您看到閃爍的時間。可能在這段時間內,您可能需要過濾出不同的WM消息。這裏是WM消息列表 - https://wiki.winehq.org/List_Of_Windows_Messages –