How to make WPF TextBox with a scrollbar automatically scroll to the bottom when lines are added?

后端 未结 4 846
时光说笑
时光说笑 2020-12-15 16:23

For example like Visual Studio\'s \"Output\" window does.

Is there a way to do it in XAML?

相关标签:
4条回答
  • 2020-12-15 16:27

    Visual Studio output window behavior is special, because it will only keep auto scrolling down if the caret is at the end of the text box, which allows you to examine the output without being disturbed if new lines are added to it.

    I've got such behavior with this code

    bool scrollToEnd = TbEvents.CaretIndex == TbEvents.Text.Length;
    TbEvents.AppendText(text + Environment.NewLine);
    if (scrollToEnd)
    {
        TbEvents.CaretIndex = TbEvents.Text.Length;
        TbEvents.ScrollToEnd();
    }
    
    0 讨论(0)
  • 2020-12-15 16:31

    There is a way to do it in XAML, you can use this Style to display it like a Console would (Be aware of the drawbacks, it just looks like a Console but does not completely behave like it)

            <Style x:Key="ConsoleTextBox" TargetType="{x:Type TextBox}">
                <Setter Property="IsReadOnly" Value="True"/>
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="TextBox">
                            <ScrollViewer RenderTransformOrigin="0.5,0.5" VerticalScrollBarVisibility="Auto">
                                <ScrollViewer.RenderTransform>
                                    <ScaleTransform ScaleY="-1"/>
                                </ScrollViewer.RenderTransform>
                                <TextBox Text="{TemplateBinding Text}" RenderTransformOrigin="0.5,0.5">
                                    <TextBox.RenderTransform>
                                        <ScaleTransform ScaleY="-1"/>
                                    </TextBox.RenderTransform>
                                </TextBox>
                            </ScrollViewer>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
    

    How does it work

    Inside the TextBox, a ScrollViewer is flipped vertically (the "new" lines are added at the Bottom)

    In the ScrollViewer, there is another Textbox which is flipped Vertically to display the Text correctly (not upside down).

    Using the Style

    Include it in your App.xaml or via ResourceDictionary and set the Style of the TextBox to ConsoleTextBox.

    <TextBox Style="{StaticResource ConsoleTextBox}"/>
    

    Drawbacks

    • When you copy the Text from this "Console" there will be no Line Breaks.
    • Scrolling with the Mouse is inverted
    0 讨论(0)
  • 2020-12-15 16:36

    You can whenever you add content to that TextBox or when you listen to the event TextChanged fire this method: TextBoxBase.ScrollToEnd().

    0 讨论(0)
  • 2020-12-15 16:52

    You could write an attached property or even better a behavior that listens to the TextChanged event and scrolls to the bottom in the callback.

    0 讨论(0)
提交回复
热议问题