2012-04-16 39 views
6

在我的WinForm應用程序中,我有一個多行TextBox控件(uiResults),用於在處理大量項目時報告進度。使用AppendText非常適合在每次更新時自動滾動到底部,但如果用戶滾動回來讀取一些較舊的數據,我需要關閉自動滾動。如果可能,我寧願遠離P/Invoke調用。在添加行時維護TextBox滾動位置

是否有可能檢測用戶是否回滾而不使用P/Invoke?現在,我只檢查SelectionStart其工作,但需要用戶插入符號從文本框的端移動停止自動滾屏:

if(uiResults.SelectionStart == uiResults.Text.Length) 
{ 
    uiResults.AppendText(result + Environment.NewLine); 
} 

我的主要問題是使用Text屬性追加一個字符串時,該文本框被滾動到開始。我試圖通過存儲插入位置並在更新後重置並滾動來解決這個問題,但是這會導致當前行移動到底部(當然,因爲ScrollToCaret滾動的距離不超過必要的距離以將脫字符視爲視圖)。

[Continued from above] 
else 
{ 
    int pos = uiResults.SelectionStart; 
    int len = uiResults.SelectionLength; 
    uiResults.Text += result + Environment.NewLine; 
    uiResults.SelectionStart = pos; 
    uiResults.SelectionLength = len; 
    uiResults.ScrollToCaret(); 
} 

回答

2

Auto-scrolling text box uses more memory than expected

在問題的代碼實現正是你所期待的。文本被添加,但滾動只發生在滾動條位於最底部時。

+0

當垂直滾動條移動並且不通過AppendText觸發WM_VSCROLL時觸發。是否有不同的信息要捕捉? – 2012-04-16 16:48:06

+0

@Brad Rem。沒有理解你的完整問題。更新。 – 2012-04-16 19:49:26

0

您是否接受另一種方法,因爲您一定會以這種方式陷入困境,解決方案將會變得複雜(您想要避免的糾結等等)。例如。假設你找到一種方法來「檢測用戶是否回滾」,並停止滾動到底部。但閱讀完該行後,用戶可能希望滾動到底部功能恢復。那麼爲什麼不給用戶一種控制自動滾動的方法。這是我會怎麼做呢?

使用一個RichTextBox顯示的數據和一個複選框來控制自動滾動,那麼你的代碼可能是這樣的:

 richTextBox1.AppendText(result + Environment.NewLine); 
     if (checkBoxAutoScroll.Checked) 
     { 
      richTextBox1.SelectionStart = richTextBox1.Text.Length; 
      richTextBox1.ScrollToCaret(); 
     } 

RichTextBox的默認情況下不會自動滾動到底部AppendText,所以第一行將始終可見(而不是新添加的行)。但是,如果用戶選中了名爲AutoScroll的複選框,我們的代碼會將richtextbox滾動到顯示新行的底部。如果用戶想要手動滾動讀取一行,他首先需要取消選中該複選框。

+1

不幸的是,當使用AppendText時,它似乎也是'RichTextBox'滾動到底部 - 但只有當控件具有焦點時。但由於用戶有時需要選擇並複製文本,因此這種方法可能無法正常工作。 – Anlo 2012-04-19 18:04:31

相關問題