是否可以讓一個WPF-TextBox自動滾動,但在移動滾動條時停止該行爲。 當用戶滾動結束時,文本框應該再次自動滾動以結束文本更改。如果用戶還沒有移動滾動條,自動滾動文本框
textBox1.ScrollToEnd();
只要用戶不移動ScrollBar,這將工作。
是否可以讓一個WPF-TextBox自動滾動,但在移動滾動條時停止該行爲。 當用戶滾動結束時,文本框應該再次自動滾動以結束文本更改。如果用戶還沒有移動滾動條,自動滾動文本框
textBox1.ScrollToEnd();
只要用戶不移動ScrollBar,這將工作。
我重做了什麼,我覺得你有你的設置:
<StackPanel>
<ScrollViewer Height="50" x:Name="_scroll">
<TextBox x:Name="_text" Width="50" Text="Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua." TextWrapping="Wrap"/>
</ScrollViewer>
<Button Click="Button_Click" Content="Add Text"/>
</StackPanel>
我假定你有一些事件編輯本框在我的設置是一個按鈕。和它的點擊處理程序:
private void Button_Click(object sender, RoutedEventArgs e)
{
var shouldScroll = _scroll.VerticalOffset == _scroll.ScrollableHeight;
_text.Text += "AAA ";
if (shouldScroll)
{
_scroll.ScrollToEnd();
}
}
這將自動滾動到文本編輯後結束,只有當滾動條位於底部時。
編輯
對於清潔的解決方案,你可以使用行爲:
public class AutoScrollingBehavior : Behavior<ScrollViewer>
{
public object UpdateTrigger
{
get { return (object)GetValue(UpdateTriggerProperty); }
set { SetValue(UpdateTriggerProperty, value); }
}
public static readonly DependencyProperty UpdateTriggerProperty =
DependencyProperty.Register("UpdateTrigger", typeof(object), typeof(AutoScrollingBehavior), new UIPropertyMetadata(Update));
private bool IsScrolledDown
{
get { return (bool)GetValue(IsScrolledDownProperty); }
set { SetValue(IsScrolledDownProperty, value); }
}
public static readonly DependencyProperty IsScrolledDownProperty =
DependencyProperty.Register("IsScrolledDown", typeof(bool), typeof(AutoScrollingBehavior), new UIPropertyMetadata(false));
private static void Update(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if ((bool)d.GetValue(IsScrolledDownProperty))
{
var scroll = ((AutoScrollingBehavior)d).AssociatedObject;
scroll.ScrollToEnd();
}
}
protected override void OnAttached()
{
AssociatedObject.Loaded += new RoutedEventHandler(AssociatedObject_Loaded);
AssociatedObject.ScrollChanged += new ScrollChangedEventHandler(AssociatedObject_ScrollChanged);
}
private void AssociatedObject_ScrollChanged(object sender, ScrollChangedEventArgs e)
{
IsScrolledDown = AssociatedObject.VerticalOffset == AssociatedObject.ScrollableHeight;
}
private void AssociatedObject_Loaded(object sender, RoutedEventArgs e)
{
IsScrolledDown = AssociatedObject.VerticalOffset == AssociatedObject.ScrollableHeight;
}
}
和XAML:
<StackPanel>
<ScrollViewer Height="50" >
<e:Interaction.Behaviors>
<local:AutoScrollingBehavior UpdateTrigger="{Binding ElementName=_text,Path=Text}" />
</e:Interaction.Behaviors>
<TextBox x:Name="_text" Width="50" Text="Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua." TextWrapping="Wrap"/>
</ScrollViewer>
<Button Click="Button_Click" Content="Add Text"/>
</StackPanel>
我發現了一個莫名其妙哈克的方式做到這一點:
public class AutoScrollTextBox : TextBox
{
ScrollViewer sv;
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
if (Template != null)
{
sv = (ScrollViewer)Template.FindName("PART_ContentHost", this);
}
}
protected override void OnTextChanged(TextChangedEventArgs e)
{
base.OnTextChanged(e);
if (sv != null && sv.ScrollableHeight == sv.VerticalOffset)
{
this.ScrollToEnd();
}
}
}
但是,這將停止如果TextBox-Template中ScrollViewer的名稱發生變化,則工作。
我想避免後面的代碼,因爲TextBox在ViewModel – 2012-08-10 09:21:53
的某些屬性上有綁定請參閱更新。對於'UpdateTrigger',你可以綁定你的模型的屬性,以避免直接綁定到控件。 – Rafal 2012-08-10 10:09:29
我剛剛使用了你寫的AutoScrollingBehavior類,它效果很好!感謝snippit – JonD 2013-03-26 15:58:53