简体   繁体   English

仅将垂直滚动条拖动到底部时才将其保持在底部

[英]Stick vertical scrollbar to bottom only when dragged to bottom

tI've got a Textbox inside a Scrollviewer: 我在Scrollviewer中有一个Textbox:

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

I want to set the vertical scrollbar to bottom only when i manually drag it to the bottom, otherwise it mustn't move from its position. 我只想在将垂直滚动条手动拖动到底部时将其设置为底部,否则它不能从其位置移动。

Ideas? 想法?

To achieve what you want (scrolling to the end only when you've already manually scrolled down there) and using the TextBox's own ScrollViewer, you just have to handle the TextChanged event and in code-behind do this: 为了实现所需的功能(仅当您已经向下手动滚动到最后时才滚动)并使用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);
}

If you need to use the extra ScrollViewer around the TextBox, then just use that ScrollViewer's ExtentHeight , ViewportHeight and VerticalOffset , and call that ScrollViewer's ScrollToBottom (instead of TextBox's ScrollToEnd ). 如果需要在TextBox周围使用额外的ScrollViewer,则只需使用ScrollViewer的ExtentHeightViewportHeightVerticalOffset ,然后调用该ScrollViewer的ScrollToBottom (而不是TextBox的ScrollToEnd )。

Keep in mind that the text input caret position is not changing, so if you try to enter text manually, the scroll is gonna jump to wherever the caret is. 请记住,文本输入插入标记的位置没有改变,因此,如果尝试手动输入文本,则滚动将跳到插入标记所在的位置。

If your TextBox is ReadOnly then I'd be inclined to use codebehind to call ScrollToHome. 如果您的TextBox是ReadOnly,那么我倾向于使用codebehind调用ScrollToHome。 If you use the TextBox's own ScrollViewer you'll need to set an explicit Height to force the ScrollViewer to display. 如果使用TextBox自己的ScrollViewer,则需要设置一个显式的Height以强制ScrollViewer显示。

XAML 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>

Codebehind 代码隐藏

private void MyTextBox_TextChanged(object sender, TextChangedEventArgs e)
{
    MyTextBox.ScrollToHome();
}

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM