Reputation: 473
tI've got a Textbox inside a Scrollviewer:
<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?
Upvotes: 1
Views: 537
Reputation: 4978
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:
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
).
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.
Upvotes: 1
Reputation: 1553
If your TextBox is ReadOnly then I'd be inclined to use codebehind to call ScrollToHome. If you use the TextBox's own ScrollViewer you'll need to set an explicit Height to force the ScrollViewer to display.
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 ";
}
Upvotes: 0