How to automatically scroll ScrollViewer - only if the user did not change scroll position
.net-3.5, c#, wpf, wpf-controls
Solution
This code will automatically scroll to end when the content grows if it was previously scrolled all the way down.
XAML:
<Window x:Class="AutoScrollTest.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Height="300" Width="300">
<ScrollViewer Name="_scrollViewer">
<Border BorderBrush="Red" BorderThickness="5" Name="_contentCtrl" Height="200" VerticalAlignment="Top">
</Border>
</ScrollViewer>
</Window>
Code behind:
using System;
using System.Windows;
using System.Windows.Threading;
namespace AutoScrollTest
{
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
DispatcherTimer timer = new DispatcherTimer();
timer.Interval = new TimeSpan(0, 0, 2);
timer.Tick += ((sender, e) =>
{
_contentCtrl.Height += 10;
if (_scrollViewer.VerticalOffset == _scrollViewer.ScrollableHeight)
{
_scrollViewer.ScrollToEnd();
}
});
timer.Start();
}
}
}
Problem
I would like to create the following behaviour in a `ScrollViewer` that wraps `ContentControl`: When the `ContentControl` height grows , the `ScrollViewer` should automatically scroll to the end. This is easy to achive by using `ScrollViewer.ScrollToEnd()`. However, if the user uses the scroll bar, the automatic scrolling shouldn't happen anymore. This is similar to what happens in VS output window for example. The problem is to know when a scrolling has happened because of user scrolling and when it happened because the content size changed. I tried to play with the `ScrollChangedEventArgs`of `ScrollChangedEvent`, but couldn't get it to work. Ideally, I do not want to handle all possible Mouse and keyboard events.