How do I create an Autoscrolling TextBox

前端 未结 6 1358
囚心锁ツ
囚心锁ツ 2021-01-31 04:02

I have a WPF application that contains a multiline TextBox that is being used to display debugging text output.

How can I set the TextBox so that as text is appended to

6条回答
  •  予麋鹿
    予麋鹿 (楼主)
    2021-01-31 04:49

    The answer provided by @BojinLi works well. After reading through the answer linked to by @GazTheDestroyer however, I decided to implement my own version for the TextBox, because it looked cleaner.

    To summarize, you can extend the behavior of the TextBox control by using an attached property. (Called ScrollOnTextChanged)

    Using it is simple:

    
    

    Here is the TextBoxBehaviour class:

    using System;
    using System.Collections.Generic;
    using System.Windows;
    using System.Windows.Controls;
    
    namespace MyNamespace
    {
        public class TextBoxBehaviour
        {
            static readonly Dictionary _associations = new Dictionary();
    
            public static bool GetScrollOnTextChanged(DependencyObject dependencyObject)
            {
                return (bool)dependencyObject.GetValue(ScrollOnTextChangedProperty);
            }
    
            public static void SetScrollOnTextChanged(DependencyObject dependencyObject, bool value)
            {
                dependencyObject.SetValue(ScrollOnTextChangedProperty, value);
            }
    
            public static readonly DependencyProperty ScrollOnTextChangedProperty =
                DependencyProperty.RegisterAttached("ScrollOnTextChanged", typeof (bool), typeof (TextBoxBehaviour), new UIPropertyMetadata(false, OnScrollOnTextChanged));
    
            static void OnScrollOnTextChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)
            {
                var textBox = dependencyObject as TextBox;
                if (textBox == null)
                {
                    return;
                }
                bool oldValue = (bool) e.OldValue, newValue = (bool) e.NewValue;
                if (newValue == oldValue)
                {
                    return;
                }
                if (newValue)
                {
                    textBox.Loaded += TextBoxLoaded;
                    textBox.Unloaded += TextBoxUnloaded;
                }
                else
                {
                    textBox.Loaded -= TextBoxLoaded;
                    textBox.Unloaded -= TextBoxUnloaded;
                    if (_associations.ContainsKey(textBox))
                    {
                        _associations[textBox].Dispose();
                    }
                }
            }
    
            static void TextBoxUnloaded(object sender, RoutedEventArgs routedEventArgs)
            {
                var textBox = (TextBox) sender;
                _associations[textBox].Dispose();
                textBox.Unloaded -= TextBoxUnloaded;
            }
    
            static void TextBoxLoaded(object sender, RoutedEventArgs routedEventArgs)
            {
                var textBox = (TextBox) sender;
                textBox.Loaded -= TextBoxLoaded;
                _associations[textBox] = new Capture(textBox);
            }
    
            class Capture : IDisposable
            {
                private TextBox TextBox { get; set; }
    
                public Capture(TextBox textBox)
                {
                    TextBox = textBox;
                    TextBox.TextChanged += OnTextBoxOnTextChanged;
                }
    
                private void OnTextBoxOnTextChanged(object sender, TextChangedEventArgs args)
                {
                    TextBox.ScrollToEnd();
                }
    
                public void Dispose()
                {
                    TextBox.TextChanged -= OnTextBoxOnTextChanged;
                }
            }
    
        }
    }
    

提交回复
热议问题