我的應用程序中有一個RichTextBox
,它在某些事件上獲取新內容。
添加新內容時,如果滾動在底部之前,我想滾動到底部,。
我該怎麼做?
更具體地說,給我麻煩的部分是確定滾動位置。WPF RichTextBox的有條件滾動?
如果很重要,RichTextBox
正在使用默認樣式和模板,幾個畫筆已更改或設置爲空,垂直滾動條可見性爲自動且爲只讀。
我的應用程序中有一個RichTextBox
,它在某些事件上獲取新內容。
添加新內容時,如果滾動在底部之前,我想滾動到底部,。
我該怎麼做?
更具體地說,給我麻煩的部分是確定滾動位置。WPF RichTextBox的有條件滾動?
如果很重要,RichTextBox
正在使用默認樣式和模板,幾個畫筆已更改或設置爲空,垂直滾動條可見性爲自動且爲只讀。
如果你想要一個富文本框新增加的文本自動滾動僅在滾動條一直拖到底部添加下面的類到您的項目
public class RichTextBoxThing : DependencyObject
{
public static bool GetIsAutoScroll(DependencyObject obj)
{
return (bool)obj.GetValue(IsAutoScrollProperty);
}
public static void SetIsAutoScroll(DependencyObject obj, bool value)
{
obj.SetValue(IsAutoScrollProperty, value);
}
public static readonly DependencyProperty IsAutoScrollProperty =
DependencyProperty.RegisterAttached("IsAutoScroll", typeof(bool), typeof(RichTextBoxThing), new PropertyMetadata(false, new PropertyChangedCallback((s, e) =>
{
RichTextBox richTextBox = s as RichTextBox;
if (richTextBox != null)
{
if ((bool)e.NewValue)
richTextBox.TextChanged += richTextBox_TextChanged;
else if ((bool)e.OldValue)
richTextBox.TextChanged -= richTextBox_TextChanged;
}
})));
static void richTextBox_TextChanged(object sender, TextChangedEventArgs e)
{
RichTextBox richTextBox = sender as RichTextBox;
if ((richTextBox.VerticalOffset + richTextBox.ViewportHeight) == richTextBox.ExtentHeight || richTextBox.ExtentHeight < richTextBox.ViewportHeight)
richTextBox.ScrollToEnd();
}
}
然後在您想要的自動滾動行爲的任何格式文本框添加IsAutoSroll財產
<RichTextBox ScrollViewer.CanContentScroll="True" ScrollViewer.VerticalScrollBarVisibility="Auto" local:RichTextBoxThing.IsAutoScroll="True"/>
基本上可以做到以下幾點:獲取滾動條,並訂閱Value
,Maximum
和Minimum
(它們都是依賴項屬性)的更改。通過這種方式,您可以通過在需要時將Value
設置爲Maximum
來控制代碼隱藏的位置。
現在,你如何訪問滾動條?有幾種方法。如果您確定哪一個是您的RichTextBox
的控件模板,您可以使用GetTemplateChild(name)
(您通過檢查例如Blend中的模板來獲得名稱)。如果你不確定,你應該更好地創建自己的模板(再次,Blend會給你一個很好的模板開始),並將其應用到你感興趣的RichTextBox
。
試試這個擴展m ethod:
public static class RichTextBoxExtensions
{
public static void ScrollIfNeeded(this RichTextBox textBox)
{
var offset = textBox.VerticalOffset + textBox.ViewportHeight;
if (Math.Abs(offset - textBox.ExtentHeight) > double.Epsilon) return;
textBox.ScrollToEnd();
}
}
而且使用這樣的:
textBox.AppendText(// Very long text here);
textBox.ScrollIfNeeded();
編輯:另類包括滾動至底部時滾動條變爲可見:
public static class RichTextBoxExtensions
{
public static void ScrollIfNeeded(this RichTextBox textBox)
{
var offset = textBox.VerticalOffset + textBox.ViewportHeight;
if (Math.Abs(offset - textBox.ExtentHeight) <= double.Epsilon)
{
textBox.ScrollToEnd();
}
else
{
var contentIsLargerThatViewport = textBox.ExtentHeight > textBox.ViewportHeight;
if (Math.Abs(textBox.VerticalOffset - 0) < double.Epsilon && contentIsLargerThatViewport)
{
textBox.ScrollToEnd();
}
}
}
}
簡單多條件滾動VerticalOffset + ViewportHeight >= ExtentHeight
示例:
bool shouldScroll = rtbx.VerticalOffset + rtbx.ViewportHeight >=
rtbx.ExtentHeight;
// changes to RichTextBox
// ...
if(shouldScroll) rtbx.ScrollToEnd();
也適用於'滾動條剛出現'的情況。
這個效果很好,但由於您比較可能相等的雙倍數,所以您應該在比較中引入一個「epsilon」。基本上我做了'rtbx.VerticalOffset + rtbx.ViewportHeight> = rtbx.ExtentHeight - 1.0;'它運作良好。我仍然投票,因爲這節省了我一些時間! – Benlitz
您可以將VerticalOffset與ViewportHeight進行比較嗎? – Paparazzi