Expander

El control Expander le permite mostrar u ocultar contenido menos importante relacionado con un fragmento de contenido principal que siempre está visible. Los elementos contenidos en el Encabezado siempre están visibles. El usuario puede expandir y contraer el área Contenido, donde se muestra el contenido secundario, interactuando con el encabezado. Cuando se expande el área de contenido, se insertan otros elementos de la interfaz de usuario aparte; no superpone otra interfaz de usuario. El control Expander puede expandirse hacia arriba o hacia abajo.

Tanto las áreas Header como las áreas Content pueden contener cualquier contenido, desde texto simple a diseños de interfaz de usuario complejos. Por ejemplo, puede usar el control para mostrar opciones adicionales para un elemento.

Un Expander contraído que se expande y luego se contrae. El encabezado tiene el texto

¿Es este el control adecuado?

Use un control Expander cuando algún contenido principal siempre esté visible, pero el contenido secundario relacionado se puede ocultar hasta que sea necesario. Esta interfaz de usuario se usa normalmente cuando el espacio de visualización es limitado y cuando la información o las opciones se pueden agrupar. Ocultar el contenido secundario hasta que sea necesario también puede ayudar a centrar al usuario en las partes más importantes de la aplicación.

UWP y WinUI 2

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.

El control Expander para aplicaciones para UWP requiere WinUI 2. Para obtener más información e instrucciones sobre la instalación, consulta el artículo WinUI 2. Existen API para este control en el espacio de nombres Microsoft.UI.Xaml.Controls.

Para usar el código de este artículo con WinUI 2, use un alias en XAML (usamos muxc) para representar las API de la Biblioteca de interfaz de usuario de Windows que se incluyen en el proyecto. Consulte Introducción a la Biblioteca de interfaz de usuario de Windows 2 para obtener más información.

xmlns:muxc="using:Microsoft.UI.Xaml.Controls"

<muxc:Expander />

Crear un Expander

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.

En este ejemplo se muestra cómo crear un Expander sencillo con el estilo predeterminado. La propiedad Header define el elemento que siempre está visible. La propiedad Content define el elemento que se puede contraer y expandir. En este ejemplo se crea un control Expander similar al de la ilustración anterior.

<Expander Header="This text is in the header"
               Content="This is in the content"/>

Propiedad Content de Expander

La propiedad Content de Expander puede ser cualquier tipo de objeto, pero normalmente es una cadena o UIElement. Para obtener más información sobre cómo establecer la propiedad Content, consulte la sección Comentarios de la clase ContentControl.

Puede usar una interfaz de usuario compleja e interactiva como contenido del Expander, incluidos los controles Expander anidados en el contenido de un Expander principal, como se muestra aquí.

Un Expander abierto con cuatro controles Expander anidados en su contenido. Cada uno de los controles Expander anidados tiene un botón de radio y texto en su encabezado

Alineación de contenido

Puede alinear el contenido estableciendo las propiedades HorizontalContentAlignment y VerticalContentAlignment en el control Expander. Al establecer estas propiedades, la alineación se aplica únicamente al contenido expandido, no al encabezado.

Controlar el tamaño de un Expander

De forma predeterminada, las áreas Encabezado y Contenido se ajustan automáticamente a su contenido. Es importante usar las técnicas correctas para controlar el tamaño de Expander y así evitar un comportamiento o apariencia no deseados.

Ancho

Si el contenido es más amplio que el encabezado, el ancho del encabezado aumenta para que coincida con el área de contenido cuando se expande, y se reduce cuando se contrae el área de contenido. Para evitar que el ancho del control cambie cuando se expanda o contraiga, puede establecer un ancho explícito o, si el control es el elemento secundario de un Panel, establezca HorizontalAlignment en Stretch y deje que el panel de diseño controle el ajuste de tamaño.

En este caso, una serie de controles Expander relacionados se ubican en StackPanel. De HorizontalAlignment cada Expander uno de los StackPanel elementos se establece en Stretch mediante un estilo en los StackPanel recursos y el ancho de StackPanel determina el ancho de los Expander controles.

<StackPanel x:Name="ExpanderStack" MaxWidth="600">
    <StackPanel.Resources>
        <Style TargetType="Expander">
            <Setter Property="HorizontalAlignment" Value="Stretch"/>
            <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
        </Style>
    </StackPanel.Resources>
    <Expander Header="Choose your crust"> ... </Expander>
    <Expander Header="Choose your sauce"> ... </Expander>
    <Expander Header="Choose your toppings"> ... </Expander>
 </StackPanel>

Tres controles de expansión apilados verticalmente, todos del mismo ancho

Height

No especifique una altura en el Expander. Si lo hace, el control reservará ese espacio incluso cuando se contraiga el área de contenido, lo que anula el propósito del Expander. Para especificar el tamaño del área de contenido expandida, establezca dimensiones de tamaño en el contenido del Expander. Si lo necesita, puede restringir el Height del contenido y hacer que el contenido se pueda desplazar.

Contenido desplazable

Si el contenido es demasiado grande para el tamaño del área de contenido, puede ajustarlo en un ScrollViewer para hacer que el área de contenido sea desplazable. El control Expander no proporciona automáticamente la funcionalidad de desplazamiento.

Cuando coloque un ScrollViewer en el contenido del Expander, establezca la altura en el control ScrollViewer para esa altura necesaria para el área de contenido. Si en cambio establece la dimensión de altura en el contenido dentro de ScrollViewer, ScrollViewer no reconoce este valor y, por lo tanto no proporciona contenido desplazable.

En el ejemplo siguiente se muestra cómo crear un control Expander que contenga texto desplazable como contenido.

<Expander Header="Expander with scrollable content">
    <ScrollViewer MaxHeight="200">
        <Grid>
            <TextBlock TextWrapping="Wrap">
                Lorem ipsum dolor sit amet, consectetur adipisicing elit, 
                sed do eiusmod tempor incididunt ut labore et dolore magna
                aliqua. Ut enim ad minim veniam, quis nostrud exercitation
                ullamco laboris nisi ut aliquip ex ea commodo consequat.
                Duis aute irure dolor in reprehenderit in voluptate velit
                esse cillum dolore eu fugiat nulla pariatur. Excepteur sint
                occaecat cupidatat non proident, sunt in culpa qui officia
                deserunt mollit anim id est laborum.
            </TextBlock>
        </Grid>
    </ScrollViewer>
</Expander>

Un Expander con texto desplazable como contenido

Expandir y contraer el área de contenido

De forma predeterminada, el Expander se contrae y se expande hacia abajo.

  • Establezca la propiedad IsExpanded en true para que el área de contenido se expanda inicialmente.
  • Establezca la propiedad ExpandDirection en Up para que el contenido se expanda hacia arriba.
<Expander IsExpanded="True" ExpandDirection="Up">

Se Expander expande o contrae mediante programación estableciendo la IsExpanded propiedad o interactuando con Header; no se puede descartar la luz.

Sugerencia

La interfaz de usuario transitoria, como Flyout o la lista desplegable abierta de un ComboBox, se cierra al hacer clic o pulsar fuera de ella. Esto se denomina cierre del elemento por cambio de foco. El área de contenido de un objeto Expander no se considera transitoria y no superpone otra interfaz de usuario, por lo que no admite el cierre por cambio de foco.

También puede controlar los eventos Expanding y Collapsed para realizar una acción cuando el contenido se muestre o se oculte. Algunos ejemplos de estos eventos:

Evento expandido

En este ejemplo, usted tiene un grupo de ampliadores y desea tener solo uno abierto a la vez. Cuando el usuario abre un Expander, usted controla el evento Expanding y contrae todos los controles Expander del grupo excepto aquel en el que el usuario hizo clic.

Precaución

En función de la aplicación y la experiencia del usuario, puede ser conveniente contraer automáticamente los controles Expander cuando el usuario expanda uno diferente. Sin embargo, esto también quita el control del usuario. Si el comportamiento puede ser útil, considere la posibilidad de convertirla en una opción que el usuario pueda establecer fácilmente.

<StackPanel x:Name="ExpanderStack">
    <Expander Header="Choose your crust"
                   Expanding="Expander_Expanding"> ... </Expander>
    <Expander Header="Choose your sauce"
                   Expanding="Expander_Expanding"> ... </Expander>
    <Expander Header="Choose your toppings"
                   Expanding="Expander_Expanding"> ... </Expander>
 </StackPanel>
// Let the user opt out of custom behavior.
private bool _autoCollapse = true;

private void Expander_Expanding(muxc.Expander sender, 
                                muxc.ExpanderExpandingEventArgs args)
{
    if (_autoCollapse == true)
    {
        foreach (muxc.Expander ex in ExpanderStack.Children)
        {
            if (ex != sender && ex.IsExpanded)
                ex.IsExpanded = false;
        }
    }
}

Evento contraído

En este ejemplo, controlará el evento Collapsed y rellenará el Header con un resumen de las opciones seleccionadas en Content.

Esta imagen muestra el Expander con el contenido expandido y las opciones seleccionadas.

Un control Expander expandido con las opciones seleccionadas que se muestran en el área de contenido

Cuando se contrae, las opciones seleccionadas se resumen en el encabezado para que el usuario pueda verlas sin abrir el Expander.

Un control Expander contraído con las opciones seleccionadas resumidas en el encabezado

<Expander IsExpanded="True"
        Expanding="Expander_Expanding"
        Collapsed="Expander_Collapsed">
    <Expander.Header>
        <Grid>
            <TextBlock Text="Choose your crust"/>
            <TextBlock x:Name="tbCrustSelections"
                       HorizontalAlignment="Right"
                       Style="{StaticResource CaptionTextBlockStyle}"/>
        </Grid>
    </Expander.Header>
    <StackPanel Orientation="Horizontal">
        <RadioButtons x:Name="rbCrustType" SelectedIndex="0">
            <x:String>Classic</x:String>
            <x:String>Whole wheat</x:String>
            <x:String>Gluten free</x:String>
        </RadioButtons>
        <RadioButtons x:Name="rbCrustStyle" SelectedIndex="0" 
                           Margin="48,0,0,0">
            <x:String>Regular</x:String>
            <x:String>Thin</x:String>
            <x:String>Pan</x:String>
            <x:String>Stuffed</x:String>
        </RadioButtons>
    </StackPanel>
</Expander>
private void Expander_Collapsed(muxc.Expander sender, 
                                muxc.ExpanderCollapsedEventArgs args)
{
    // Update the header with options selected in the content.
    tbCrustSelections.Text = rbCrustType.SelectedItem.ToString() +
        ", " + rbCrustStyle.SelectedItem.ToString();
}

Estilo ligero

Puede modificar Style y ControlTemplate predeterminados para dar al control una apariencia única. Consulte la sección Plantilla y estilo de control en los documentos de la API de Expander para obtener una lista de los recursos de tema disponibles. Para obtener más información, consulte la sección de estilos ligeros del artículo Controles de estilo.

Recomendaciones

  • Use un Expander cuando el espacio de visualización está limitado y es posible que algún contenido secundario esté oculto hasta que el usuario lo solicite.

Ejemplos de código

Este XAML crea el grupo de controles Expander que se muestran en otras partes de este artículo. El código de los controladores de eventos Expanding y Collapsed también se muestra en las secciones anteriores.

<StackPanel x:Name="ExpanderStack" MaxWidth="600">
    <StackPanel.Resources>
        <Style TargetType="Expander">
            <Setter Property="HorizontalAlignment" Value="Stretch"/>
            <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
        </Style>
    </StackPanel.Resources>
    <Expander IsExpanded="True"
                   Expanding="Expander_Expanding"
                   Collapsed="Expander_Collapsed">
        <Expander.Header>
            <Grid>
                <TextBlock Text="Choose your crust"/>
                <TextBlock x:Name="tbCrustSelections" 
                           HorizontalAlignment="Right"
        Style="{StaticResource CaptionTextBlockStyle}"/>
            </Grid>
        </Expander.Header>
        <StackPanel Orientation="Horizontal">
            <RadioButtons x:Name="rbCrustType" SelectedIndex="0">
                <x:String>Classic</x:String>
                <x:String>Whole wheat</x:String>
                <x:String>Gluten free</x:String>
            </RadioButtons>
            <RadioButtons x:Name="rbCrustStyle" SelectedIndex="0" 
                   Margin="48,0,0,0">
                <x:String>Regular</x:String>
                <x:String>Thin</x:String>
                <x:String>Pan</x:String>
                <x:String>Stuffed</x:String>
            </RadioButtons>
        </StackPanel>
    </Expander>
    
    <Expander Header="Choose your sauce" Margin="24"
            Expanding="Expander_Expanding">
        <RadioButtons SelectedIndex="0" MaxColumns="2">
            <x:String>Classic red</x:String>
            <x:String>Garlic</x:String>
            <x:String>Pesto</x:String>
            <x:String>Barbecue</x:String>
        </RadioButtons>
    </Expander>

    <Expander Header="Choose your toppings"
                   Expanding="Expander_Expanding">
        <StackPanel>
            <Expander>
                <Expander.Header>
                    <RadioButton GroupName="Toppings" Content="House special"/>
                </Expander.Header>
                <TextBlock Text="Cheese, pepperoni, sausage, black olives, mushrooms"
                           TextWrapping="WrapWholeWords"/>
            </Expander>
            <Expander>
                <Expander.Header>
                    <RadioButton GroupName="Toppings" Content="Vegetarian"/>
                </Expander.Header>
                <TextBlock Text="Cheese, mushrooms, black olives, green peppers, artichoke hearts"
                           TextWrapping="WrapWholeWords"/>
            </Expander>
            <Expander>
                <Expander.Header>
                    <RadioButton GroupName="Toppings" Content="All meat"/>
                </Expander.Header>
                <TextBlock Text="Cheese, pepperoni, sausage, ground beef, salami"
                           TextWrapping="WrapWholeWords"/>
            </Expander>
            <Expander>
                <Expander.Header>
                    <RadioButton GroupName="Toppings" Content="Choose your own"/>
                </Expander.Header>
                <StackPanel Orientation="Horizontal">
                    <StackPanel>
                        <CheckBox Content="Cheese"/>
                        <CheckBox Content="Pepperoni"/>
                        <CheckBox Content="Sausage"/>
                    </StackPanel>
                    <StackPanel>
                        <CheckBox Content="Ground beef"/>
                        <CheckBox Content="Salami"/>
                        <CheckBox Content="Mushroom"/>
                    </StackPanel>
                    <StackPanel>
                        <CheckBox Content="Black olives"/>
                        <CheckBox Content="Green peppers"/>
                        <CheckBox Content="Artichoke hearts"/>
                    </StackPanel>
                </StackPanel>
            </Expander>
        </StackPanel>
    </Expander>
</StackPanel>