仅当拖动到底部时,才将垂直滚动条粘到底部

本文关键字:底部 垂直 滚动条 拖动 | 更新日期: 2023-09-27 17:56:53

t我在滚动查看器中有一个文本框:

<ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto">
    <TextBox IsReadOnly="True" TextWrapping="Wrap" Text="{Binding Messages, Converter={StaticResource TimedStringListToStringConverter}, UpdateSourceTrigger=PropertyChanged}"/>
</ScrollViewer>

我只想在手动将其拖动到底部时才将垂直滚动条设置为底部,否则它不能从其位置移动。

想法?

仅当拖动到底部时,才将垂直滚动条粘到底部

若要实现所需的内容(仅在已手动向下滚动到末尾)并使用 TextBox 自己的 ScrollViewer,只需处理 TextChanged 事件并在代码隐藏中执行以下操作:

private void TextBox_TextChanged(object sender, TextChangedEventArgs e)
{
    var textBox = sender as TextBox;
    var max = (textBox.ExtentHeight - textBox.ViewportHeight);
    var offset = textBox.VerticalOffset;
    if (max != 0 && max == offset)
        this.Dispatcher.BeginInvoke(new Action(() =>
            {
                textBox.ScrollToEnd();
            }),
            System.Windows.Threading.DispatcherPriority.Loaded);
}

如果您需要在文本框周围使用额外的 ScrollViewer,则只需使用该 ScrollViewer 的 ExtentHeightViewportHeightVerticalOffset ,并调用该 ScrollViewer 的ScrollToBottom(而不是 TextBox 的 ScrollToEnd)。

请记住,文本输入插入符号

的位置没有变化,因此如果您尝试手动输入文本,滚动将跳转到插入符号所在的位置。

如果你的文本框是只读的,那么我倾向于使用代码隐藏来调用ScrollToHome。如果使用文本框自己的滚动查看器,则需要设置显式高度以强制显示滚动查看器。

XAML

<Grid x:Name="LayoutRoot">
    <Grid.RowDefinitions>
        <RowDefinition />
        <RowDefinition />
    </Grid.RowDefinitions>
    <TextBox x:Name="MyTextBox"
                Grid.Row="0"
                Width="80"
                Height="100"
                FontSize="20"
                IsReadOnly="True"
                ScrollViewer.HorizontalScrollBarVisibility="Auto"
                ScrollViewer.VerticalScrollBarVisibility="Auto"
                TextChanged="MyTextBox_TextChanged"
                TextWrapping="Wrap" />
    <Button Grid.Row="1"
            Width="50"
            Height="50"
            Click="Button_Click"
            Content="OK" />
</Grid>

代码隐藏

private void MyTextBox_TextChanged(object sender, TextChangedEventArgs e)
{
    MyTextBox.ScrollToHome();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
    MyTextBox.Text += "TEXT ";
}