仅在拖动到底部时将垂直滚动条粘到底部

时间:2015-06-18 14:50:56

标签: c# wpf scrollbar scrollviewer

我在Scrollviewer中有一个文本框:

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

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

想法?

2 个答案:

答案 0 :(得分:1)

要实现您想要的功能(只有在您已经手动向下滚动到那里时滚动到最后)并使用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);
}

如果您需要在TextBox周围使用额外的ScrollViewer,那么只需使用ScrollViewer的ExtentHeightViewportHeightVerticalOffset,然后调用ScrollViewer&#39; s ScrollToBottom(而不是TextBox&#39; s ScrollToEnd)。

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

答案 1 :(得分:0)

如果您的TextBox是ReadOnly,那么我倾向于使用代码隐藏来调用ScrollToHome。如果您使用TextBox自己的ScrollViewer,则需要设置显式高度以强制ScrollViewer显示。

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 ";
}