How do I create an Autoscrolling TextBox

前端 未结 6 1455
囚心锁ツ
囚心锁ツ 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:44

    This solution is inspired by Scott Ferguson's solution with the attached property, but avoids storing an internal dictionary of associations and thereby has somewhat shorter code:

        using System;
        using System.Windows;
        using System.Windows.Controls;
    
        namespace AttachedPropertyTest
        {
            public static class TextBoxUtilities
            {
                public static readonly DependencyProperty AlwaysScrollToEndProperty = DependencyProperty.RegisterAttached("AlwaysScrollToEnd",
                                                                                                                          typeof(bool),
                                                                                                                          typeof(TextBoxUtilities),
                                                                                                                          new PropertyMetadata(false, AlwaysScrollToEndChanged));
    
                private static void AlwaysScrollToEndChanged(object sender, DependencyPropertyChangedEventArgs e)
                {
                    TextBox tb = sender as TextBox;
                    if (tb != null) {
                        bool alwaysScrollToEnd = (e.NewValue != null) && (bool)e.NewValue;
                        if (alwaysScrollToEnd) {
                            tb.ScrollToEnd();
                            tb.TextChanged += TextChanged;
                        } else {
                            tb.TextChanged -= TextChanged;
                        }
                    } else {
                        throw new InvalidOperationException("The attached AlwaysScrollToEnd property can only be applied to TextBox instances.");
                    }
                }
    
                public static bool GetAlwaysScrollToEnd(TextBox textBox)
                {
                    if (textBox == null) {
                        throw new ArgumentNullException("textBox");
                    }
    
                    return (bool)textBox.GetValue(AlwaysScrollToEndProperty);
                }
    
                public static void SetAlwaysScrollToEnd(TextBox textBox, bool alwaysScrollToEnd)
                {
                    if (textBox == null) {
                        throw new ArgumentNullException("textBox");
                    }
    
                    textBox.SetValue(AlwaysScrollToEndProperty, alwaysScrollToEnd);
                }
    
                private static void TextChanged(object sender, TextChangedEventArgs e)
                {
                    ((TextBox)sender).ScrollToEnd();
                }
            }
        }
    

    As far as I can tell, it behaves exactly as desired. Here's a test case with several text boxes in a window that allows the attached AlwaysScrollToEnd property to be set in various ways (hard-coded, with a CheckBox.IsChecked binding and in code-behind):

    Xaml:

        
            
                
            
    
            
                
                    
                    
                
                
                    
                    
                    
                    
                    
                    
                
    
                
    
                
                
                
                
                
                

    Code-Behind:

        using System;
        using System.Windows;
        using System.Windows.Controls;
    
        namespace AttachedPropertyTest
        {
            public partial class Window1 : Window
            {
                public Window1()
                {
                    InitializeComponent();
                }
    
                void Button_Click(object sender, RoutedEventArgs e)
                {
                    TextBoxUtilities.SetAlwaysScrollToEnd(tb3, true);
                }
            }
        }
    

提交回复
热议问题