I want to detect (preferably through an event) when any content is added, changed, etc. in a FlowDocument
and when it does I want to cause a FlowDocumentScrollViewer
displaying the FlowDocument
to automatically scroll to the end.
相关问题
- VNC control for WPF application
- Use JS/jQuery to scroll a div's content that h
- WPF Binding from System.Windows.SystemParameters.P
- Jscrollpane - Fires a function when isAtBottom
- XAML: Applying styles to nested controls
You can use the following extension method to get the inner scroll viewer:
Additionally you can use these extension methods before adding content to check the scroll position the scrollviewer itself (in case you want to scroll -only- if the scroll viewer was already at the end for example):
Afterwards just call scrollViewer.ScrollToEnd() for example.
After hooking up to a TextChanged Event, you can simply use:
But, this works only on a FlowDocumentPageViewer, and also on a FlowDocumentReader (with pages ViewingModes), for a FlowDocumentScrollViewer you should use the visual tree as mentioned
Are you using a RichTextBox to do the editing? If so you should just be able to hook the
TextChanged
event and then call theScrollToVerticalOffset
method with the value from theViewportHeight
property.You can detect changes in the
FlowDocument
by creating a text range and monitoring it for changes. Scrolling to the bottom is more difficult because you have to find theScrollViewer
. Also for performance you don't want redo all the scrolling calculations on every change, so you should useDispatcherOperations
.Putting it all together, this code should do the trick:
where
FindFirstVisualDescendantOfType
is a simple depth-first prefix search of the visual tree usingVisualTreeHelper.GetChildrenCount()
andVisualTreeHelper.GetChild()
and returning the first Visual found of the specified type.Note that for full generality I don't precompute scrollViewer at the top of the code because the
FlowDocumentScrollViewer
's template can change. If this won't happen, this code can be speeded up by calling.ApplyTemplate()
on theFlowDocumentScrollViewer
and then computingscrollViewer
before the event handler is registered:Note that we cannot simply call
scrollViewer.GetTemplateChild("PART_ContentHost")
and skip the visual tree search becauseGetTemplateChild
is protected.