Partilhar via


Expansor

O controle Expander permite mostrar ou ocultar conteúdo menos importante relacionado a um conteúdo principal sempre visível. Os itens contidos no cabeçalho estão sempre visíveis. O usuário pode expandir e recolher a área Conteúdo, onde o conteúdo secundário é exibido, interagindo com o cabeçalho. Quando a área de conteúdo é expandida, ela tira outros elementos da interface do usuário do caminho; ele não sobrepõe outra interface do usuário. O Expander pode se expandir para cima ou para baixo.

As áreas Header e Content podem conter qualquer conteúdo, desde texto simples até layouts complexos de interface do usuário. Por exemplo, você pode usar o controle para mostrar opções adicionais para um item.

Um Expansor recolhido que é expandido e então recolhido. O Cabeçalho tem o texto

Esse é o controle correto?

Use um Expander quando algum conteúdo primário precisar estar sempre visível, mas o conteúdo secundário relacionado puder ficar oculto até que seja necessário. Essa interface do usuário costuma ser usada quando o espaço de exibição é limitado e quando as informações ou opções podem ser agrupadas. Ocultar o conteúdo secundário até que ele seja necessário também pode ajudar a concentrar o usuário nas partes mais importantes do seu aplicativo.

UWP e WinUI 2

Importante

As informações e exemplos neste artigo são otimizados para aplicativos que usam o SDK do Aplicativo Windows e o WinUI 3, mas geralmente são aplicáveis a aplicativos UWP que usam o WinUI 2. Consulte a referência de API da UWP para obter informações e exemplos específicos da plataforma.

Esta seção contém informações necessárias para usar o controle em um aplicativo UWP ou WinUI 2.

O Expansor para aplicativos UWP requer WinUI 2. Para obter mais informações, incluindo instruções de instalação, confira WinUI 2. As APIs para esse controle existem no namespace Microsoft.UI.Xaml.Controls.

Para usar o código neste artigo com a WinUI 2, use um alias em XAML (usamos muxc) para representar as APIs da Biblioteca de Interface do Usuário do Windows incluídas em seu projeto. Confira Introdução à WinUI 2 para obter mais informações.

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

<muxc:Expander />

Criar um expansor

O aplicativo Galeria da WinUI 3 inclui exemplos interativos da maioria dos controles, recursos e funcionalidades da WinUI 3. Obtenha o aplicativo na Microsoft Store ou o código-fonte no GitHub

Este exemplo mostra como criar um Expansor simples com a estilização padrão. A propriedade Header define o elemento que está sempre visível. A propriedade Content define o elemento que pode ser recolhido e expandido. Este exemplo cria um Expander que se parece com a ilustração anterior.

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

Conteúdo do expansor

A propriedade Conteúdo de um Expander pode ser qualquer tipo de objeto, mas normalmente é uma cadeia de caracteres ou UIElement. Para obter mais detalhes sobre como definir a propriedade Content, consulte a seção Comentários da classe ContentControl.

Você pode usar uma interface do usuário complexa e interativa Expander, incluindo controles Expander aninhados no conteúdo de um Expander pai conforme mostrado aqui.

Um Expansor aberto com quatro controles Expansor aninhados em seu conteúdo. Cada um dos controles Expansor aninhados tem um botão de opção e texto em seu cabeçalho

Alinhamento de conteúdo

Você pode alinhar o conteúdo definindo as propriedades HorizontalContentAlignment e VerticalContentAlignment no controle Expander. Ao definir essas propriedades, o alinhamento se aplica somente ao conteúdo expandido, não ao cabeçalho.

Controlar o tamanho de um Expansor

Por padrão, as áreas Cabeçalho e Conteúdo são dimensionadas automaticamente para se ajustarem ao conteúdo. É importante usar as técnicas corretas para controlar o tamanho do Expander para evitar aparência ou comportamento indesejados.

Width

Se o conteúdo for maior que o cabeçalho, a largura do cabeçalho aumentará para corresponder à área de conteúdo quando expandida e diminuirá quando a área de conteúdo for recolhida. Para evitar que a largura do controle seja alterada quando expandido ou recolhido, você pode definir uma largura explícita ou, se o controle for filho de um Painel, defina HorizontalAlignment como Esticar e permitir que o painel de layout controle o dimensionamento.

Aqui, uma série de controles relacionados Expander são colocados em um StackPanel. O HorizontalAlignment de cada Expander um no StackPanel é definido como Stretch usando um Style nos Recursos, e a StackPanel largura do StackPanel determina a largura dos 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>

Três controles expansores empilhados verticalmente, todos com a mesma largura

Altura

Não especifique uma Altura no Expander. Se você fizer isso, o controle reservará esse espaço mesmo quando a área de conteúdo for recolhida, tornando o Expander obsoleto. Para especificar o tamanho da área de conteúdo expandida, defina as dimensões de tamanho no conteúdo do Expander. Se necessário, você pode restringir o Height do conteúdo e torná-lo rolável.

Conteúdo rolável

Se o conteúdo for muito grande para o tamanho da área de conteúdo, você poderá encapsular o conteúdo em um ScrollViewer para tornar a área de conteúdo rolável. O controle Expander não fornece automaticamente a capacidade de rolagem.

Quando você colocar um ScrollViewer no Expander conteúdo, defina a altura no controle ScrollViewer como a altura necessária para a área de conteúdo. Se, em vez disso, você definir a dimensão de altura no conteúdo dentro do ScrollViewer, ScrollViewer não reconhece essa configuração e, portanto, não fornece conteúdo rolável.

O exemplo a seguir mostra como criar um controle Expander que contém texto rolável como conteúdo.

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

Um Expansor com texto rolável como conteúdo

Expandir e recolher a área de conteúdo

Por padrão, o Expansor é recolhido e se expande para baixo.

  • Defina a propriedade IsExpanded para true que a área de conteúdo seja inicialmente expandida.
  • Defina a propriedade ExpandDirection como Up para fazer com que o conteúdo se expanda para cima.
<Expander IsExpanded="True" ExpandDirection="Up">

An Expander é expandido ou recolhido programaticamente definindo a IsExpanded propriedade ou interagindo com o Header; ele não pode ser descartado à luz.

Dica

A interface do usuário transitória, como uma Flyout ou a lista suspensa aberta de um ComboBox, é fechada quando você clica ou toca fora dela. Esse recurso é chamado de light-dismiss. A área de conteúdo de um Expander não é considerada transitória e não sobrepõe outra interface do usuário, portanto, não oferece suporte a light-dismiss.

Você também pode manipular os eventos Expandido e Colapsado para executar uma ação quando o conteúdo é mostrado ou ocultado. Veja a seguir alguns exemplos desses eventos:

Evento em expansão

Neste exemplo, você tem um grupo de expansores e recomenda-se ter apenas um aberto por vez. Quando o usuário abre um Expander, você manipula o evento Expandindo e recolhe todos os controles Expander no grupo diferente daquele em que o usuário clicou.

Cuidado

Dependendo do seu aplicativo e da experiência do usuário, pode ser uma conveniência recolher automaticamente os controles Expander quando o usuário expande um diferente. No entanto, isso também tira o controle do usuário. Se o comportamento puder ser útil, considere torná-lo uma opção que o usuário possa definir facilmente.

<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 recolhido

Neste exemplo, você manipula o evento Recolhido e preencher o Header com um resumo das opções selecionadas no Content.

Esta imagem mostra o Expander com o conteúdo expandido e as opções selecionadas.

Um controle Expansor expandido com opções selecionadas mostradas na área de conteúdo

Quando recolhidas, as opções selecionadas são resumidas no cabeçalho para que o usuário ainda possa vê-las sem abrir o Expander.

Um controle Expansor recolhido com opções selecionadas resumidas no cabeçalho

<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();
}

Estilização leve

Você pode modificar Style e ControlTemplate para fornecer ao controle uma aparência exclusiva. Confira a seção Estilo de Controle e Modelo da documentação da API Expansor para obter uma lista dos recursos de tema disponíveis. Para obter mais informações, confira a seção de estilo leve do artigo Controles de estilo.

Recomendações

  • Use um Expander quando o espaço de exibição for limitado e algum conteúdo secundário puder ficar oculto até que o usuário o solicite.

Exemplos de código

Esse XAML cria o grupo de controles Expander mostrado em outras partes deste artigo. O código para os manipuladores de eventos Expanding e Collapsed também é mostrado nas seções 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>