2012-08-10 78 views

回答

3

我重做了什麼,我覺得你有你的設置:

<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> 
+0

我想避免後面的代碼,因爲TextBox在ViewModel – 2012-08-10 09:21:53

+0

的某些屬性上有綁定請參閱更新。對於'UpdateTrigger',你可以綁定你的模型的屬性,以避免直接綁定到控件。 – Rafal 2012-08-10 10:09:29

+0

我剛剛使用了你寫的AutoScrollingBehavior類,它效果很好!感謝snippit – JonD 2013-03-26 15:58:53

0

我發現了一個莫名其妙哈克的方式做到這一點:

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的名稱發生變化,則工作。