Controles del visor de desplazamiento

Cuando la interfaz de usuario tenga más contenido que el que se puede mostrar en un área, use un control del visor de desplazamiento.

Los visores de desplazamiento permiten que el contenido se extienda más allá de los límites de la ventanilla (área visible). Para acceder a dicho contenido, los usuario manipulan la superficie del visor de desplazamiento mediante entrada táctil, la rueda del mouse, el teclado o un controlador para juegos, o bien mediante el uso del cursor del ratón o del lápiz óptico para interactuar con la barra de desplazamiento del visor de desplazamiento.

En función de la situación, la barra de desplazamiento del visor de desplazamiento usa dos visualizaciones diferentes, que se muestran en la siguiente ilustración: el indicador de movimiento panorámico (izquierda) y la barra de desplazamiento con el control tradicional (derecha).

A screenshot that illustrates a panning scrollbar, a 2 pixel wide vertical line at the right edge of the content.

A screenshot that illustrates the standard scrollbar, a 6 pixel wide vertical line with an up arrow button at the top, and a down arrow at the bottom.

Importante

WinUI 3 tiene dos controles del visor de desplazamiento diferentes disponibles: ScrollViewer y ScrollView. Siempre que hablamos genéricamente sobre los controles del visor de desplazamiento, la información se aplica a ambos controles.

Desplazamiento, movimiento panorámico y zoom

Use un control del visor de desplazamiento para permitir el desplazamiento, el movimiento panorámico y el zoom del contenido.

  • Desplazamiento: mover el contenido vertical u horizontalmente arrastrando la barra de desplazamiento con el control o usando la rueda de desplazamiento de un mouse.
  • Movimiento panorámico: mover contenido vertical u horizontalmente mediante la entrada táctil o manuscrita.
  • Zoom: aumento o disminución ópticos de la escala del contenido.

La barra de desplazamiento es consciente del método de entrada del usuario y lo usa para determinar la visualización que se va a usar.

  • Cuando la región se desplaza sin manipular directamente la barra de desplazamiento, por ejemplo de manera táctil, aparece el indicador de movimiento panorámico y muestra la posición de desplazamiento actual.
  • Cuando se mueve el cursor del ratón o del lápiz sobre el indicador de movimiento panorámico, se transforma en la barra de desplazamiento tradicional. Al arrastrar la barra de desplazamiento, la región de desplazamiento se manipula con el pulgar.

An animation that shows the scroll bar transform from the narrow panning indicator to the traditional thumb when the cursor moves over it.

Nota:

Cuando la barra de desplazamiento está visible, se superpone como 16 píxeles al contenido dentro del ScrollViewer. Para garantizar un buen diseño de la experiencia del usuario, querrás asegurarte de que ningún contenido interactivo queda oculto por esta superposición. Además, si prefieres que no se superponga la experiencia del usuario, deja 16 píxeles de espaciado interno en el borde de la ventanilla para la barra de desplazamiento.

Ventanilla y extensión

Un visor de desplazamiento se compone de dos regiones principales que son importantes para comprender su funcionalidad. El área que incluye todo el contenido desplazable, tanto oculto como visible, es la extensión. El área visible del control donde se muestra el contenido es la ventanilla.

A block of text that extends beyond the viewport, or visible area of the control.

Hay varias API disponibles que permiten obtener el alto y el ancho de estas regiones, así como el alto y el ancho desplazables, que son la diferencia entre el tamaño de extensión y el tamaño de la ventanilla.

Recomendaciones

  • Siempre que sea posible, diseñe para el desplazamiento vertical en lugar del horizontal.
  • Utilice el desplazamiento lateral en un eje para las regiones de contenido que se extienden más allá de los límites de una ventana gráfica (vertical u horizontal). Utilice el desplazamiento lateral en dos ejes para las regiones de contenido que se extienden más allá de ambos límites de la ventana gráfica (vertical y horizontal).
  • Use la funcionalidad de desplazamiento integrada en: la vista de elementos, la vista de lista, la vista de cuadrícula, el cuadro combinado, el cuadro de lista, el cuadro de entrada de texto y los controles de navegación centralizada. Con estos controles, si hay demasiados elementos que mostrar al mismo tiempo, el usuario puede desplazarse horizontal o verticalmente por la lista de elementos.
  • Si quiere que el usuario pueda generar una vista panorámica en ambas direcciones sobre un área mayor y, posiblemente, también aplicar zoom. Por ejemplo, si quiere permitir que el usuario pueda generar una vista panorámica y aplicar zoom sobre una imagen a tamaño completo (en lugar de una imagen con tamaño ajustado a la pantalla) y, a continuación, colocar la imagen dentro de un visor de desplazamiento.
  • Si el usuario va a desplazarse a lo largo un fragmento de texto largo, configure el visor de desplazamiento para que se desplace solamente de manera vertical.
  • Use un visor de desplazamiento para contener un solo objeto. Tenga en cuenta que ese objeto puede ser un panel de diseño que contenga a su vez cualquier número de objetos.
  • Si necesita controlar los eventos de puntero para una clase UIElement en una vista desplazable (como ScrollViewer o ListView), debe deshabilitar explícitamente la compatibilidad con los eventos de manipulación en el elemento de la vista mediante una llamada a UIElement.CancelDirectmanipulation(). Para volver a habilitar los eventos de manipulación en la vista, llame a UIElement.TryStartDirectManipulation.

UWP y WinUI 2

Nota:

El control ScrollView solo está disponible en WinUI 3. Para UWP y WinUI 2, use el control ScrollViewer.

Importante

La información y los ejemplos de este artículo están optimizados para aplicaciones que usan el SDK de Aplicaciones para Windows y WinUI 3, pero generalmente son aplicables a las aplicaciones para UWP que usan WinUI 2. Consulte el material de referencia de las API de UWP para obtener información y ejemplos específicos de la plataforma.

Esta sección contiene información que necesita para usar el control en una aplicación para UWP o WinUI 2.

Existen API para este control en el espacio de nombres Windows.UI.Xaml.Controls.

Se recomienda usar la versión más reciente de WinUI 2 para obtener los estilos, las plantillas y las características más actuales de todos los controles. WinUI 2.2 o de versiones posteriores incluye una nueva plantilla para este control que usa esquinas redondeadas. Para obtener más información, consulta Radio de redondeo.

Crear un visor de desplazamiento

La aplicación WinUI 3 Gallery incluye ejemplos interactivos de la mayoría de los controles, características y funcionalidades de WinUI 3. Obtenga la aplicación de Microsoft Store u obtenga el código fuente en GitHub.

Un control de visor de desplazamiento se puede usar para hacer que el contenido sea desplazable mediante el ajuste explícito del contenido en el visor de desplazamiento o la colocación un visor de desplazamiento en la plantilla de control de un control de contenido.

Visor de desplazamiento en una plantilla de control

Es habitual que exista un control del visor de desplazamiento como parte de otros controles. Un elemento del visor de desplazamiento mostrará una ventanilla junto con las barras de desplazamiento solo cuando el espacio de diseño del control de host tenga una limitación menor que el tamaño del contenido expandido.

ItemsView incluye un control ScrollView en su plantilla. Puede acceder a ScrollView mediante la propiedad ItemsView.ScrollView.

Las plantillas ListView y GridView siempre incluyen un ScrollViewer. TextBox y RichEditBox también incluyen un ScrollViewer en sus plantillas. Para influir en algunos de los comportamientos y de las propiedades de la parte integrada ScrollViewer, ScrollViewer define una serie de propiedades adjuntas XAML que se pueden establecer en estilos y usar en enlaces de plantilla. Para obtener más información sobre las propiedades adjuntas, consulte Introducción a las propiedades adjuntas.

Establecer contenido desplazable

El contenido de un visor de desplazamiento se vuelve desplazable cuando es mayor que la ventanilla del visor de desplazamiento

En este ejemplo se establece un Rectangle como el contenido del control ScrollView. El usuario solo ve una parte de 500x400 de ese rectángulo y puede desplazarse para ver el resto.

<ScrollView Width="500" Height="400">
    <Rectangle Width="1000" Height="800">
        <Rectangle.Fill>
            <LinearGradientBrush StartPoint="0,0" EndPoint="1,1">
                <GradientStop Color="Yellow" Offset="0.0" />
                <GradientStop Color="Red" Offset="0.25" />
                <GradientStop Color="Blue" Offset="0.75" />
                <GradientStop Color="LimeGreen" Offset="1.0" />
            </LinearGradientBrush>
        </Rectangle.Fill>
    </Rectangle>
</ScrollView>

Layout

En el ejemplo anterior, el tamaño del rectángulo se establece explícitamente para que sea más grande que el visor de desplazamiento. En los casos en los que el contenido del visor de desplazamiento puede crecer de forma natural, como en una lista o un bloque de texto, puede configurar el visor de desplazamiento para permitir que su contenido (la extensión) se expanda verticalmente, horizontalmente, de ambas maneras o de ninguna.

Por ejemplo, este bloque de texto aumentará horizontalmente hasta que su contenedor primario lo restrinja y, a continuación, ajuste el texto y lo extienda verticalmente.

<TextBlock Text="{x:Bind someText}" TextWrapping="WrapWholeWords"/>

Cuando el bloque de texto se ajusta en un visor de desplazamiento, el visor de desplazamiento restringe su crecimiento horizontal y vertical.

Vertical significa que el contenido está restringido horizontalmente, pero puede crecer verticalmente más allá de los límites de la ventanilla, y el usuario puede desplazar el contenido hacia arriba y hacia abajo.

A block of text that extends vertically beyond the viewport, or visible area of the control, with a vertical scroll bar shown.

Horizontal significa que el contenido está restringido verticalmente, pero puede crecer horizontalmente más allá de los límites de la ventanilla, y el usuario puede desplazar el contenido a izquierda y derecha.

A block of text that extends horizontally beyond the viewport, or visible area of the control, with a horizontal scroll bar shown.

Visibilidad de la barra de desplazamiento

Los controles ScrollViewer y ScrollView usan medios ligeramente diferentes para configurar el desplazamiento horizontal y vertical del contenido.

  • En el control ScrollViewer, las propiedades VerticalScrollBarVisibility y HorizontalScrollBarVisibility controlan la visibilidad de las barras de desplazamiento y si se permite el desplazamiento en una dirección determinada. Cuando una propiedad se establece en Disabled, la interacción del usuario no puede desplazar el contenido en esa dirección.
    • Los valores predeterminados son: VerticalScrollBarVisibility="Auto", HorizontalScrollBarVisibility="Disabled"
  • En el control ScrollView, las propiedades VerticalScrollBarVisibility y HorizontalScrollBarVisibility controlan solo la visibilidad de las barras de desplazamiento.
    • Los valores predeterminados son: VerticalScrollBarVisibility="Auto", HorizontalScrollBarVisibility="Auto"

En esta tabla se describen las opciones de visibilidad de estas propiedades.

Valor Descripción
Auto Una barra de desplazamiento solo aparece cuando la ventanilla no puede mostrar todo el contenido.
Deshabilitado (solo ScrollViewer) Una barra de desplazamiento no aparece incluso cuando la ventanilla no puede mostrar todo el contenido. El desplazamiento por interacción del usuario está deshabilitado. (El desplazamiento mediante programación sigue siendo posible).
Oculta Una barra de desplazamiento no aparece incluso cuando la ventanilla no puede mostrar todo el contenido. El desplazamiento todavía está habilitado y puede producirse a través de interacción táctil, del teclado o de la rueda del mouse.
Visible Siempre aparece una barra de desplazamiento. (En los diseños actuales de la experiencia de usuario, la barra de desplazamiento solo aparece cuando el cursor del mouse está sobre él a menos que la ventanilla no pueda mostrar todo el contenido).

(ScrollViewer usa la enumeración ScrollBarVisibility; ScrollView usa la enumeración ScrollingScrollBarVisibility).

Orientación

El control ScrollView tiene una propiedad ContentOrientation que permite controlar el diseño del contenido. Esta propiedad determina cómo puede crecer el contenido cuando no está restringido explícitamente. Si Height y Width se establecen explícitamente en el contenido, ContentOrientation no tiene ningún efecto.

En esta tabla se muestran las opciones ContentOrientation para ScrollView y la configuración equivalente para ScrollViewer.

Orientación ScrollView ScrollViewer
Vertical ContentOrientation="Vertical" VerticalScrollBarVisibility="[Auto][Visible][Hidden]"
HorizontalScrollBarVisibility="Disabled"
Horizontal ContentOrientation="Horizontal" VerticalScrollBarVisibility="Disabled"
HorizontalScrollBarVisibility="[Auto][Visible][Hidden]"
Ambos ContentOrientation="Both" VerticalScrollBarVisibility="[Auto][Visible][Hidden]"
HorizontalScrollBarVisibility="[Auto][Visible][Hidden]"
Ninguno ContentOrientation="None"
VerticalScrollBarVisibility="Disabled"
HorizontalScrollBarVisibility="Disabled"

Diseño vertical

De forma predeterminada, el diseño de contenido (orientación) de un visor de desplazamiento es vertical.

En este ejemplo, se usa un ItemsRepeater como Content de ScrollView. UniformGridLayout para ItemsRepeater coloca los elementos horizontalmente en una fila hasta que se queda sin espacio (500px en este ejemplo) y después coloca el siguiente elemento en la fila siguiente. ItemsRepeater puede ser más alto que los 400px que puede ver el usuario, pero el usuario puede desplazar el contenido verticalmente.

El valor ContentOrientation predeterminado es Vertical, por lo que no se necesitan cambios en ScrollView.

<ScrollView Width="500" Height="400">
    <ItemsRepeater ItemsSource="{x:Bind Albums}"
                   ItemTemplate="{StaticResource MyTemplate}">
        <ItemsRepeater.Layout>
            <UniformGridLayout RowSpacing="8" ColumnSpacing="8"/>
        </ItemsRepeater.Layout>
    </ItemsRepeater>
</ScrollView>

Diseño horizontal

En este ejemplo, el contenido es un StackPanel que está estableciendo sus elementos horizontalmente. La configuración del visor de desplazamiento se cambia para admitir el desplazamiento horizontal y deshabilitar el desplazamiento vertical.

La propiedad ScrollView de ContentOrientation se establece en Horizontal para permitir que el contenido crezca horizontalmente tanto como sea necesario.

<ScrollView Width="500" Height="400" ContentOrientation="Horizontal">
    <StackPanel Orientation="Horizontal">
        <Button Width="200" Content="Button 1"/>
        <Button Width="200" Content="Button 2"/>
        <Button Width="200" Content="Button 3"/>
        <Button Width="200" Content="Button 4"/>
        <Button Width="200" Content="Button 5"/>
    </StackPanel>
</ScrollView>

Desplazamiento mediante programación

Las propiedades de desplazamiento del visor de desplazamiento son de solo lectura, pero se proporcionan métodos para permitirle desplazarse mediante programación.

Para el control ScrollView, llame al método ScrollTo y pase los desplazamientos horizontales y verticales a los que desplazarse. En este caso, el desplazamiento solo es vertical, por lo que se usa el valor HorizontalOffset actual. Para desplazarse a la parte superior, se usa un VerticalOffset de 0. Para desplazarse hasta la parte inferior, VerticalOffset es igual que ScrollableHeight.

<Button Content="Scroll to top" Click="ScrollTopButton_Click"/>
<Button Content="Scroll to bottom" Click="ScrollBottomButton_Click"/>
<ScrollView x:Name="scrollView" Width="500" Height="400">
    <StackPanel>
        <Button Width="200" Content="Button 1"/>
        <Button Width="200" Content="Button 2"/>
        <Button Width="200" Content="Button 3"/>
        <Button Width="200" Content="Button 4"/>
        <Button Width="200" Content="Button 5"/>
    </StackPanel>
</ScrollView>
private void ScrollTopButton_Click(object sender, RoutedEventArgs e)
{
    scrollView.ScrollTo(
        horizontalOffset: scrollView.HorizontalOffset,
        verticalOffset: 0);
}

private void ScrollBottomButton_Click(object sender, RoutedEventArgs e)
{
    scrollView.ScrollTo(
        horizontalOffset: scrollView.HorizontalOffset,
        verticalOffset: scrollView.ScrollableHeight);
}

ScrollView también proporciona un método ScrollBy que permite desplazarse vertical u horizontalmente por un delta especificado desde el desplazamiento actual.

Acercar

Puede usar un visor de desplazamiento para permitir al usuario acercar y alejar ópticamente el contenido. Las interacciones de zoom óptico se realizan a través de los gestos de reducir y estirar (separar los dedos sirve para hace zoom y juntarlos, para deshacerlo) o presionando la tecla Ctrl mientras se desplaza la rueda del mouse. Para obtener más información sobre el zoom, consulte Zoom óptico y cambio de tamaño.

Para habilitar el zoom por interacción del usuario, establezca la propiedad ZoomMode en Enabled (es Disabled de forma predeterminada). Los cambios en la propiedad ZoomMode surten efecto inmediatamente y pueden afectar a una interacción en curso del usuario.

En este ejemplo se muestra una imagen encapsulada en un visor de desplazamiento configurado para permitir el zoom.

<ScrollView Width="500" Height="400"
            ContentOrientation="Both"
            ZoomMode="Enabled">
    <Image Source="Assets/rainier.jpg"/>
</ScrollView>

En este caso, la imagen no está restringida por el visor de desplazamiento, por lo que inicialmente se muestra en su tamaño nativo. Si el origen de la imagen es más grande que la ventanilla, el usuario tendrá que reducirla para verla entera, y puede que este no sea el comportamiento previsto.

A picture of a mountain zoomed in so far that only blue sky and clouds in the upper left of the picture are visible.

En el ejemplo siguiente se muestra cómo configurar el visor de desplazamiento para restringir la imagen a la ventanilla, de manera que se cargue inicialmente reducida y el usuario pueda ampliarla y desplazarse si lo desea.

A picture of a mountain zoomed out so that the foreground, mountain, and sky are all visible.

Para restringir la imagen a la ventanilla de ScrollView, establezca la propiedad ContentOrientation en None. Dado que la visibilidad de la barra de desplazamiento no está vinculada a esta restricción, las barras de desplazamiento aparecen automáticamente cuando el usuario se acerca.

<ScrollView Width="500" Height="400"
            ContentOrientation="None"
            ZoomMode="Enabled">
    <Image Source="Assets/rainier.jpg"/>
</ScrollView>

Factor de zoom

Use las propiedades MinZoomFactor y MaxZoomFactor para controlar la medida en que el usuario puede acercar el contenido. Estas propiedades son eficaces para las interacciones del usuario y el zoom mediante programación.

  • Los valores predeterminados son: MinZoomFactor="0.1", MaxZoomFactor="10.0"
<ScrollView Width="500" Height="400"
            ContentOrientation="Both"
            ZoomMode="Enabled" 
            MinZoomFactor="1.0" MaxZoomFactor="8.0">
    <Image Source="Assets/rainier.png"/>
</ScrollView>

Zoom mediante programación

La propiedad ZoomFactor es de solo lectura, pero se proporcionan métodos para permitirle aplicar zoom mediante programación. Un uso típico de esto es conectar el visor de desplazamiento a un control deslizante que controla la cantidad de zoom o a un botón para restablecer el nivel de zoom. (Consulte ScrollViewer en la aplicación WinUI 3 Gallery para ver un control deslizante de zoom de ejemplo).

Para el control ScrollView, llame al método ZoomTo y pase el nuevo factor de zoom como primer parámetro.

<Slider Header="Zoom" IsEnabled="True"
        Maximum="{x:Bind scrollControl.MaxZoomFactor, Mode=OneWay}"
        Minimum="{x:Bind scrollControl.MinZoomFactor, Mode=OneWay}"
        StepFrequency="0.1"
        ValueChanged="ZoomSlider_ValueChanged" />
<ScrollView Width="500" Height="400"
            ContentOrientation="None"
            ZoomMode="Enabled">
    <Image Source="Assets/rainier.png"/>
</ScrollView>
private void ZoomSlider_ValueChanged(object sender, RangeBaseValueChangedEventArgs e)
{
    if (scrollControl != null)
    {
        scrollControl.ZoomTo(
            zoomFactor: (float)e.NewValue,
            centerPoint: null)
    }
}

ScrollView también proporciona un método ZoomBy que permite acercar y alejar el zoom por un delta especificado desde el nivel de zoom actual.

Obtener el código de ejemplo