WPF RichTextBox's conditionally scroll?

richtextbox, wpf

Solution

If you want a rich textbox to auto scroll with new added text only when the scrollbar has been dragged to the bottom add the following class to your project

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();
    }
}

then on any rich textbox that you want the auto scroll behaviour add the IsAutoSroll property

<RichTextBox ScrollViewer.CanContentScroll="True" ScrollViewer.VerticalScrollBarVisibility="Auto" local:RichTextBoxThing.IsAutoScroll="True"/> 

Problem

I've a `RichTextBox` in my app which is getting new content on certain events. When new content is added, I'd like to scroll to the bottom, only if the scroll was at the bottom before. How do I do this? More specifically, the part that gives me trouble is determining the scroll position. If it matters, the `RichTextBox` is using the default style and template, a few brushes changed or set to null, vertical scrollbar visibility is Auto and it's read-only.

Original source