Scroll WPF FlowDocumentScrollViewer from code?

I have a FlowDocumentScrollViewer. I want to automatically scroll to the bottom when adding text.

<FlowDocumentScrollViewer Name="Scroller"> <FlowDocument Foreground="White" Name="docDebug" FontFamily="Terminal"> <Paragraph Name="paragraphDebug"/> </FlowDocument> </FlowDocumentScrollViewer> 

In the code, I add Inlines to the paragraph, but when there is a lot of text, I would be able to just scroll down using the code instead of the user having to do this.

Any suggestions?

+6
c # wpf flowdocument
source share
5 answers

The other answers given here are a bit perplexing, as I don't see any public ScrollViewer property in the FlowDocumentScrollViewer.

I cracked a problem like this. Remember that this method can return null during initialization:

 public static ScrollViewer FindScrollViewer(this FlowDocumentScrollViewer flowDocumentScrollViewer) { if (VisualTreeHelper.GetChildrenCount(flowDocumentScrollViewer) == 0) { return null; } // Border is the first child of first child of a ScrolldocumentViewer DependencyObject firstChild = VisualTreeHelper.GetChild(flowDocumentScrollViewer, 0); if (firstChild == null) { return null; } Decorator border = VisualTreeHelper.GetChild(firstChild, 0) as Decorator; if (border == null) { return null; } return border.Child as ScrollViewer; } 
+6
source share

to try:

 Scroller.ScrollViewer.ScrollToEnd(); 

Where "Scroller" is the name of your FlowDocumentScrollViewer.

EDIT . I wrote this answer too fast. FlowDocumentScrollViewer does not provide a ScrollViewer property. I really extended the FlowDocumentScrollViewer class and implemented the ScrollViewer property myself. Here is the implementation:

  /// <summary> /// Backing store for the <see cref="ScrollViewer"/> property. /// </summary> private ScrollViewer scrollViewer; /// <summary> /// Gets the scroll viewer contained within the FlowDocumentScrollViewer control /// </summary> public ScrollViewer ScrollViewer { get { if (this.scrollViewer == null) { DependencyObject obj = this; do { if (VisualTreeHelper.GetChildrenCount(obj) > 0) obj = VisualTreeHelper.GetChild(obj as Visual, 0); else return null; } while (!(obj is ScrollViewer)); this.scrollViewer = obj as ScrollViewer; } return this.scrollViewer; } } 
+12
source share

I had a similar problem: I need a text area that could contain my text, knows how to wrap it, fills in its parent control and scrolls.

At first I tried using TextBlock with ScrollViewer, and I think it worked, but for some reason I wanted to use FlowDocument instead of FlowDocumentScrollViewer. This last one did not work, and I just could not leave the battle unattended, so I tried to find solutions, and here's how I got here. I tried to apply workarounds presented in the answers to the original question, however, none of them I have developed (I use .NET 4.5, it may work in other versions, but I do not know about it).

I also tried to use one FlowDocument, but the control contains some user interface elements that I do not need. So, I came up with a different solution.

  <ScrollViewer VerticalScrollBarVisibility="Auto"> <FlowDocumentScrollViewer HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden"> <FlowDocument> 

It is right. It works! Calling ScrollViewer.ScrollToBottom () just works! ScrollViewer allows you to scroll, and FlowDocumentScrollViewer removes user interface elements from FlowDocument. Hope this helps!


Apparently, my design had a flaw, because this way the FlowDocument does not scroll using the mouse scroll wheel. However, setting the IsHitTestVisible property of the FlowDocumentScrollViewer control to False allows this.

+9
source share

This question was asked 7 years ago, now I have the same problem and I find a simple solution. The following code adds a section to the Flowdocument, which is similar to a paragraph, then scrolls to the end.

 private void addSection(Section section) { section.Loaded += section_Loaded; fdoc.Blocks.Add(section); } private void section_Loaded(object sender, RoutedEventArgs e)//scroll to end { var sec = sender as Section; if (sec != null) { sec.BringIntoView(); } } 
0
source share

This may be a very late answer, but I found a way to do this.

 //after your FlowDocumentScrollViewer(for example, x:Name="fdsv") loaded ScrollViewer sv = fdsv.Template.FindName("PART_ContentHost", fdsv) as ScrollViewer; sv.ScrollToBottom(); sv.ScrollToTop(); sv.ScrollToVerticalOffset(100); // etc. 

Check IScrollInfo and ScrollViewer for details.

Hope this helps you.

0
source share

All Articles