2009-02-18 15 views
6

Tengo un FlowDocumentScrollViewer Quiero desplazarme automáticamente a la parte inferior cuando se agrega texto.Desplácese a WPF FlowDocumentScrollViewer desde el código?

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

En el código agrego inlines al párrafo, pero cuando no es la cantidad de texto que habría gustaría ser capaz de simplemente desplazarse hacia abajo utilizando el código en lugar de tener el usuario hacerlo.

¿Alguna sugerencia?

Respuesta

6

Las otras respuestas que se dan aquí son un poco desconcertante, ya que no veo cualquier propiedad pública "ScrollViewer" en la FlowDocumentScrollViewer.

Hackeé el problema de esta manera. Tenga en cuenta que este método puede devolver null durante la inicialización:

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; 
} 
+0

Gracias por señalar el error en mi respuesta. Lo corregí. –

+0

Tenga en cuenta que este método FindScrollViewer no funciona actualmente, sin embargo, la versión de la respuesta de John Myczek sí lo hace. – Niall

+0

Por "actualmente", ¿te refieres a WPF 4.0? Viéndolo nuevamente, podría ser frágil y estar roto por cambios en los controles exactos que se encuentran entre el FlowDocumentScrollViewer y el ScrollViewer causados ​​por la versión o el estilo, por lo que un enfoque más simple e ignorante puede ser mejor. – Anthony

12

intento:

Scroller.ScrollViewer.ScrollToEnd(); 

Donde "desplazador" es el nombre de su FlowDocumentScrollViewer.

EDIT: Escribí esta respuesta demasiado rápido. FlowDocumentScrollViewer no expone una propiedad ScrollViewer. De hecho, extendí la clase FlowDocumentScrollViewer e implementé la propiedad ScrollViewer por mi cuenta. Aquí está la aplicación:

/// <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; 
    } 
    } 
+0

Me sale y error esto no se puede convertir en un DependencyObject – Paparazzi

9

me he enfrentado a un problema similar: quería una zona textual que podría sostener mi texto, es capaz de envolver, que se llena su control principal y es desplazable.

En primer lugar he tratado de utilizar un TextBlock con un ScrollViewer y creo que funcionó, pero por alguna razón he querido utilizar un FlowDocument lugar con un FlowDocumentScrollViewer. Esto último no funcionó y no podía dejar la lucha sin ataduras, así que traté de encontrar soluciones y así es como llegué aquí. Intenté aplicar las soluciones provisionales presentadas en las respuestas a la pregunta original; sin embargo, ninguna de las soluciones me funcionó (estoy usando .NET 4.5, quizás funcione en otras versiones, pero no sé).

He intentado usar un solo FlowDocument por sí mismo también, pero el control contiene algunos elementos de la interfaz de usuario que no quería. Entonces, se me ocurrió otra solución.

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

Así es. ¡Funciona! Llamar al ScrollViewer.ScrollToBottom() ¡simplemente funciona! El ScrollViewer habilita el desplazamiento y FlowDocumentScrollViewer elimina los elementos de la interfaz de usuario del FlowDocument. ¡Espero eso ayude!


Al parecer, mi construcción tenía un defecto, porque de esta manera el FlowDocument no es desplazable a través de la rueda de desplazamiento de un ratón.Sin embargo, la configuración de la propiedad FlowDocumentScrollViewer del control IsHitTestVisible a False resuelve esto.

0

Hace 7 años se planteó esta pregunta, ahora tengo el mismo problema y encuentro una solución simple. El siguiente código agrega una Sección al Documento de Flujo, que a su vez a Párrafo, luego desplácese hasta el final.

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

Esta puede ser una respuesta muy tardía, pero he encontrado una forma de hacerlo.

//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. 

Comprobar IScrollInfo y ScrollViewer para más detalles.

Espero que esto te ayude.

Cuestiones relacionadas