C# 通用应用程序:以编程方式设置新文本后自动滚动到文本框底部

C# universal app: automatically scroll to bottom of textbox after setting new text programmatically

{
   var stringBuilder = new StringBuilder(OutputTextBox.Text);
   stringBuilder.Append("sample text\n");
   OutputTextBox.Text = stringBuilder.ToString();
}

如何在插入新文本后自动滚动到文本框底部?我读过它与 .append 方法一起工作。不幸的是,这种方法在通用应用程序中不存在。文本框是只读的。

.xaml 看起来像这样:

<ScrollViewer Name="ScrollViewer" HorizontalAlignment="Left" Height="175" VerticalAlignment="Top" Width="337" RenderTransformOrigin="1.774,9.9" Margin="95,95,-370,-223">
            <TextBox x:Name="OutputTextBox" HorizontalAlignment="Left" Height="175" VerticalAlignment="Top" Width="337" RenderTransformOrigin="1.774,9.9" TextWrapping="Wrap" AcceptsReturn="True" IsReadOnly="True"/>
</ScrollViewer>

我尝试做的是:

        await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
        {
            var stringBuilder = new StringBuilder(OutputTextBox.Text);
            stringBuilder.Append("sample text\n");
            OutputTextBox.Text = stringBuilder.ToString();
            ScrollViewer.ChangeView(0.0f, double.MaxValue, 1.0f);
        });

设置新文本后尝试像这样在 ScrollViewer 上更改视图:

ScrollViewer.ChangeView(0.0f, double.MaxValue, 1.0f);

或使用ScrollViewer.ScrollToEnd();

并将此设置添加到 ScrollView:

VerticalScrollBarVisibility="Visible" AllowDrop="False" ManipulationMode="Control"

你有这样的:

<ScrollViewer Name="ScrollViewer" HorizontalAlignment="Left" Height="175" VerticalAlignment="Top" Width="337" RenderTransformOrigin="1.774,9.9" Margin="95,95,-370,-223" VerticalScrollBarVisibility="Visible" AllowDrop="False" ManipulationMode="Control">

TextBox has an embedded ScrollViewer by default. We can find it in TextBox styles and templates。无需再将 TextBox 放入另一个 ScrollViewer 中。

Scrolling using a scroll-wheel or touch is automatically enabled when needed. However, vertical scrollbars are not shown by default. You can show the vertical scrollbars by setting the ScrollViewer.VerticalScrollBarVisibility to Auto on the embedded ScrollViewer, as shown here.

<TextBox AcceptsReturn="True" TextWrapping="Wrap" 
         MaxHeight="172" Width="300" Header="Description"
         ScrollViewer.VerticalScrollBarVisibility="Auto"/>

有关详细信息,请参阅TextBox class备注中的启用多行输入部分。

所以要滚动到文本框的底部,我们可以先获取嵌入的ScrollViewer,然后使用ChangeView滚动文本框内的文本。下面是一个简单的例子:

private void ScrolltoBottom(TextBox textBox)
{
    var grid = (Grid)VisualTreeHelper.GetChild(textBox, 0);
    for (var i = 0; i < VisualTreeHelper.GetChildrenCount(grid); i++)
    {
        object obj = VisualTreeHelper.GetChild(grid, i);
        if (!(obj is ScrollViewer)) continue;
        ((ScrollViewer)obj).ChangeView(0.0f, ((ScrollViewer)obj).ExtentHeight, 1.0f);
        break;
    }
}

但是,使用ChangeView方法时会出现一个问题,在TextBox中使用此方法后,我们无法使用滚轮或触摸向后滚动。作为解决方法,我们可以临时使用 ScrollViewer.ScrollToVerticalOffset method

private void ScrolltoBottom(TextBox textBox)
{
    var grid = (Grid)VisualTreeHelper.GetChild(textBox, 0);
    for (var i = 0; i < VisualTreeHelper.GetChildrenCount(grid); i++)
    {
        object obj = VisualTreeHelper.GetChild(grid, i);
        if (!(obj is ScrollViewer)) continue;
        //((ScrollViewer)obj).ChangeView(0.0f, ((ScrollViewer)obj).ExtentHeight, 1.0f);
        ((ScrollViewer)obj).ScrollToVerticalOffset(((ScrollViewer)obj).ExtentHeight);
        break;
    }
}