开发者

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

For ex开发者_StackOverflowample like Visual Studio's "Output" window does.

Is there a way to do it in XAML?


You can handle the TextChanged event, which will fire whenever you change that TextBox's Text: TextBoxBase.ScrollToEnd().


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


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.


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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜