Nota
O acesso a esta página requer autorização. Podes tentar iniciar sessão ou mudar de diretório.
O acesso a esta página requer autorização. Podes tentar mudar de diretório.
O sistema de layout XAML fornece dimensionamento automático de elementos, painéis de layout e estados visuais para ajudá-lo a criar uma interface do usuário responsiva. Com um layout responsivo, você pode fazer com que seu aplicativo tenha uma ótima aparência em telas com diferentes tamanhos de janelas, resoluções, densidades de pixels e orientações. Você também pode usar XAML para reposicionar, redimensionar, refluir, mostrar/ocultar, substituir ou rearquitetar a interface do usuário do seu aplicativo, conforme discutido em Técnicas de design responsivo. Aqui, discutimos como implementar layouts responsivos com XAML.
Layouts fluidos com propriedades e painéis
A fundação de um layout responsivo é o uso apropriado de propriedades e painéis de layout XAML para reposicionar, redimensionar e reorganizar conteúdo de modo fluido.
O sistema de layout XAML oferece suporte a layouts estáticos e fluidos. Em um layout estático, você dá aos controles tamanhos e posições de pixels explícitos. Quando o usuário altera a resolução ou a orientação do dispositivo, a interface do usuário não é alterada. Os layouts estáticos podem ser cortados em diferentes formatos e tamanhos de exibição. Por outro lado, layouts fluidos encolhem, crescem e refluem para responder ao espaço visual disponível em um dispositivo.
Na prática, você usa uma combinação de elementos estáticos e fluidos para criar sua interface do usuário. Você ainda usa elementos e valores estáticos em alguns lugares, mas certifique-se de que a interface do usuário geral seja responsiva a diferentes resoluções, tamanhos de tela e modos de exibição.
Aqui, discutimos como usar propriedades XAML e painéis de layout para criar um layout fluido.
Propriedades de layout
As propriedades de layout controlam o tamanho e a posição de um elemento. Para criar um layout fluido, use o dimensionamento automático ou proporcional para os elementos e permita que os painéis de layout posicionem seus filhos conforme necessário.
Aqui estão algumas propriedades de layout comuns e como usá-las para criar layouts fluidos.
Altura e Largura
As propriedades Height e Width especificam o tamanho de um elemento. Você pode usar valores fixos medidos em pixels efetivos ou pode usar dimensionamento automático ou proporcional.
O dimensionamento automático redimensiona os elementos da interface do usuário para se adequarem ao conteúdo ou ao contêiner pai. Você também pode usar o dimensionamento automático com as linhas e colunas de uma grade. Para usar o dimensionamento automático, defina Altura e/ou Largura dos elementos da interface do usuário como Automático.
Observação
Se um elemento é redimensionado para seu conteúdo ou seu contêiner depende de como o contêiner pai lida com o dimensionamento de seus filhos. Para obter mais informações, consulte Painéis de layout mais adiante neste artigo.
O dimensionamento proporcional, também chamado de dimensionamento em estrela, distribui o espaço disponível entre as linhas e colunas de uma grade por proporções ponderadas. Em XAML, os valores de estrela são expressos como * (ou n* para dimensionamento ponderado de estrelas). Por exemplo, para especificar que uma coluna é 5 vezes maior do que a segunda coluna em um layout de 2 colunas, use "5*" e "*" para as propriedades Width nos elementos ColumnDefinition .
Este exemplo combina dimensionamento fixo, automático e proporcional em uma grade com 4 colunas.
| Coluna | Sizing | Description |
|---|---|---|
| Column_1 | Automático | A coluna será dimensionada para se ajustar ao seu conteúdo. |
| Column_2 | * | Depois que as colunas Auto são calculadas, a coluna obtém parte da largura restante. Column_2 terá metade da largura de Column_4. |
| Column_3 | 44 | A coluna terá 44 pixels de largura. |
| Column_4 | 2* | Depois que as colunas Auto são calculadas, a coluna obtém parte da largura restante. Column_4 terá o dobro da largura Column_2. |
A largura da coluna padrão é "*", portanto, não é necessário definir explicitamente esse valor para a segunda coluna.
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition/>
<ColumnDefinition Width="44"/>
<ColumnDefinition Width="2*"/>
</Grid.ColumnDefinitions>
<TextBlock Text="Column 1 sizes to its content." FontSize="24"/>
</Grid>
No designer XAML do Visual Studio, o resultado tem esta aparência.
Para obter o tamanho de um elemento em tempo de execução, use as propriedades somente de leitura ActualHeight e ActualWidth em vez de Height e Width.
Restrições de tamanho
Ao usar o dimensionamento automático em sua interface do usuário, talvez ainda seja necessário colocar restrições no tamanho de um elemento. Você pode definir as propriedades MinWidth/MaxWidth e MinHeight/MaxHeight para especificar valores que restringem o tamanho de um elemento enquanto permitem o redimensionamento de fluidos.
Em uma grade, MinWidth/MaxWidth também pode ser usado com definições de coluna, e MinHeight/MaxHeight pode ser usado com definições de linha.
Alinhamento
Use as propriedades HorizontalAlignment e VerticalAlignment para especificar como um elemento deve ser posicionado dentro de seu contentor pai.
- Os valores para HorizontalAlignment são Left, Center, Right e Stretch.
- Os valores para VerticalAlignment são Top, Center, Bottom e Stretch.
Com o alinhamento Stretch , os elementos preenchem todo o espaço fornecido no contêiner pai. O "Stretch" é o padrão para ambas as propriedades de alinhamento. No entanto, alguns controles, como Button, substituem esse valor em seu estilo padrão. Qualquer elemento que possa ter elementos filhos pode tratar o valor Stretch para as propriedades HorizontalAlignment e VerticalAlignment de forma única. Por exemplo, um elemento que usa os valores Stretch padrão colocados numa grade estende-se para preencher a célula que o contém. O mesmo elemento colocado em um Canvas ajusta-se ao seu conteúdo. Para obter mais informações sobre como cada painel lida com o valor Stretch, consulte o artigo Painéis de layout .
Para saber mais, veja o artigo Alinhamento, margem e preenchimento e as páginas de referência HorizontalAlignment e VerticalAlignment .
Visibilidade
Você pode revelar ou ocultar um elemento definindo a sua propriedade Visibility como um dos valores da enumeração Visibility: Visible ou Collapsed. Quando um elemento é recolhido, ele não ocupa espaço no layout da interface do usuário.
Você pode alterar a propriedade Visibility de um elemento no código ou em um estado visual. Quando a visibilidade de um elemento é alterada, todos os seus elementos filho também são alterados. Você pode substituir seções da sua UI revelando um painel enquanto colapsa outro.
Sugestão
Quando você tem elementos em sua interface do usuário que são recolhidos por padrão, os objetos ainda são criados na inicialização, mesmo que eles não estejam visíveis. Você pode adiar o carregamento desses elementos até que eles sejam mostrados usando o atributo x:Load para atrasar a criação dos objetos. Isso pode melhorar o desempenho da inicialização. Para obter mais informações, consulte o atributo x:Load.
Recursos de estilo
Não é necessário definir cada valor de propriedade individualmente em um controle. Normalmente, é mais eficiente agrupar valores de propriedade em um recurso Style e aplicar o Style a um controle. Isso é especialmente verdadeiro quando você precisa aplicar os mesmos valores de propriedade a muitos controles. Para saber mais sobre como usar estilos, consulte Controlo de Estilos.
Painéis de layout
Para posicionar objetos visuais, você deve colocá-los em um painel ou outro objeto de contêiner. A estrutura XAML fornece várias classes de painel, como Canvas, Grid, RelativePanel e StackPanel, que servem como contêineres e permitem posicionar e organizar os elementos da interface do usuário dentro deles.
A principal coisa a considerar ao escolher um painel de layout é como o painel posiciona e dimensiona os seus elementos filhos. Também pode ser necessário considerar como os elementos filho sobrepostos são dispostos uns sobre os outros.
Aqui está uma comparação dos principais recursos dos controles de painel fornecidos na estrutura XAML.
| Painel de Controlo | Description |
|---|---|
| Canvas | O Canvas não suporta uma interface de utilizador flexível; são controlados todos os aspetos de posicionamento e dimensionamento dos elementos filho. Normalmente, você o usa para casos especiais, como a criação de gráficos ou para definir pequenas áreas estáticas de uma interface do usuário adaptável maior. Você pode usar código ou estados visuais para reposicionar elementos em tempo de execução. |
| Grelha |
A Grade suporta o redimensionamento fluido de elementos filhos. Você pode usar código ou estados visuais para reposicionar e rearranjar elementos. |
| RelativePanel | |
| StackPanel | |
| VariableSizedWrapGrid |
Para obter informações detalhadas e exemplos desses painéis, consulte Painéis de layout.
Os painéis de layout permitem organizar sua interface do usuário em grupos lógicos de controles. Ao usá-los com as configurações de propriedade apropriadas, obtém-se algum suporte para redimensionamento, reposicionamento e refluxo automáticos de elementos da interface de utilizador. No entanto, a maioria dos layouts de interface do usuário precisa de mais modificações quando há alterações significativas no tamanho da janela. Para isso, você pode usar estados visuais.
Layouts adaptáveis com estados visuais e gatilhos de estado
Use estados visuais para fazer alterações significativas na interface do usuário com base no tamanho da janela ou em outras alterações.
Quando a janela do aplicativo cresce ou diminui além de um determinado limite, convém alterar as propriedades de layout para reposicionar, redimensionar, reorganizar, revelar ou substituir seções da interface do usuário. Você pode definir diferentes estados visuais para sua interface do usuário e aplicá-los quando a largura ou a altura da janela ultrapassar um limite especificado.
Um VisualState define valores de propriedade que são aplicados a um elemento quando ele está em um estado específico. Você agrupa estados visuais em um VisualStateManager que aplica o VisualState apropriado quando as condições especificadas são atendidas. Um AdaptiveTrigger fornece uma maneira fácil de definir o limite (também chamado de 'ponto de interrupção') onde um estado é aplicado em XAML. Ou, você pode chamar o método VisualStateManager.GoToState em seu código para aplicar o estado visual. Exemplos de ambas as maneiras são mostrados nas próximas seções.
Definir estados visuais no código
Para aplicar um estado visual do código, chame o método VisualStateManager.GoToState . Por exemplo, para aplicar um estado quando a janela do aplicativo é de um tamanho específico, manipule o evento SizeChanged e chame GoToState para aplicar o estado apropriado.
Aqui, um VisualStateGroup contém duas definições de VisualState. O primeiro, DefaultState, está vazio. Quando é aplicado, os valores definidos na página XAML são aplicados. O segundo, WideState, altera a propriedade DisplayMode do SplitView para Inline e abre o painel. Esse estado é aplicado no manipulador de eventos SizeChanged se a largura da janela for maior que 640 pixels efetivos.
Observação
O Windows não fornece uma maneira de seu aplicativo detetar o dispositivo específico em que seu aplicativo está sendo executado. Ele pode dizer a família de dispositivos (desktop, etc) em que o aplicativo está sendo executado, a resolução efetiva e a quantidade de espaço na tela disponível para o aplicativo (o tamanho da janela do aplicativo). Recomendamos a definição de estados visuais para tamanhos de tela e pontos de interrupção.
<Page ...
SizeChanged="CurrentWindow_SizeChanged">
<Grid>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup>
<VisualState x:Name="DefaultState">
<Storyboard>
</Storyboard>
</VisualState>
<VisualState x:Name="WideState">
<Storyboard>
<ObjectAnimationUsingKeyFrames
Storyboard.TargetProperty="SplitView.DisplayMode"
Storyboard.TargetName="mySplitView">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<SplitViewDisplayMode>Inline</SplitViewDisplayMode>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames
Storyboard.TargetProperty="SplitView.IsPaneOpen"
Storyboard.TargetName="mySplitView">
<DiscreteObjectKeyFrame KeyTime="0" Value="True"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<SplitView x:Name="mySplitView" DisplayMode="CompactInline"
IsPaneOpen="False" CompactPaneLength="20">
<!-- SplitView content -->
<SplitView.Pane>
<!-- Pane content -->
</SplitView.Pane>
</SplitView>
</Grid>
</Page>
private void CurrentWindow_SizeChanged(object sender, Windows.UI.Core.WindowSizeChangedEventArgs e)
{
if (e.Size.Width > 640)
VisualStateManager.GoToState(this, "WideState", false);
else
VisualStateManager.GoToState(this, "DefaultState", false);
}
// YourPage.h
void CurrentWindow_SizeChanged(winrt::Windows::Foundation::IInspectable const& sender, winrt::Windows::UI::Xaml::SizeChangedEventArgs const& e);
// YourPage.cpp
void YourPage::CurrentWindow_SizeChanged(IInspectable const& sender, SizeChangedEventArgs const& e)
{
if (e.NewSize.Width > 640)
VisualStateManager::GoToState(*this, "WideState", false);
else
VisualStateManager::GoToState(*this, "DefaultState", false);
}
Definir estados visuais na marcação XAML
Antes do Windows 10, as definições do VisualState exigiam objetos do Storyboard para alterações de propriedade, e você tinha que chamar GoToState no código para aplicar o estado. Isso é mostrado no exemplo anterior. Você ainda verá muitos exemplos que usam essa sintaxe ou pode ter código existente que a usa.
A partir do Windows 10, você pode usar a sintaxe Setter simplificada mostrada aqui e pode usar um StateTrigger em sua marcação XAML para aplicar o estado. Você usa gatilhos de estado para criar regras simples que acionam automaticamente alterações de estado visual em resposta a um evento do aplicativo.
Este exemplo faz a mesma coisa que o exemplo anterior, mas usa a sintaxe Setter simplificada em vez de um Storyboard para definir alterações de propriedade. E, em vez de chamar GoToState, ele usa o gatilho de estado AdaptiveTrigger interno para aplicar o estado. Quando você usa gatilhos de estado, não precisa definir um vazio DefaultState. As configurações padrão são reaplicadas automaticamente quando as condições do gatilho de estado não são mais atendidas.
<Page ...>
<Grid>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup>
<VisualState>
<VisualState.StateTriggers>
<!-- VisualState to be triggered when the
window width is >=640 effective pixels. -->
<AdaptiveTrigger MinWindowWidth="640" />
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="mySplitView.DisplayMode" Value="Inline"/>
<Setter Target="mySplitView.IsPaneOpen" Value="True"/>
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<SplitView x:Name="mySplitView" DisplayMode="CompactInline"
IsPaneOpen="False" CompactPaneLength="20">
<!-- SplitView content -->
<SplitView.Pane>
<!-- Pane content -->
</SplitView.Pane>
</SplitView>
</Grid>
</Page>
Importante
No exemplo anterior, a propriedade anexada VisualStateManager.VisualStateGroups é definida no elemento Grid . Ao usar StateTriggers, sempre verifique se VisualStateGroups está anexado ao primeiro filho da raiz para que os gatilhos entrem em vigor automaticamente. (Aqui, Grid é o primeiro filho do elemento raiz Page .)
Sintaxe da propriedade anexada
Em um VisualState, você normalmente define um valor para uma propriedade de controle ou para uma das propriedades anexadas do painel que contém o controle. Ao definir uma propriedade anexada, use parênteses ao redor do nome da propriedade anexada.
Este exemplo mostra como definir a propriedade anexada RelativePanel.AlignHorizontalCenterWithPanel em um TextBox chamado myTextBox. O primeiro XAML usa a sintaxe ObjectAnimationUsingKeyFrames e o segundo usa a sintaxe Setter .
<!-- Set an attached property using ObjectAnimationUsingKeyFrames. -->
<ObjectAnimationUsingKeyFrames
Storyboard.TargetProperty="(RelativePanel.AlignHorizontalCenterWithPanel)"
Storyboard.TargetName="myTextBox">
<DiscreteObjectKeyFrame KeyTime="0" Value="True"/>
</ObjectAnimationUsingKeyFrames>
<!-- Set an attached property using Setter. -->
<Setter Target="myTextBox.(RelativePanel.AlignHorizontalCenterWithPanel)" Value="True"/>
Gatilhos de estado personalizados
Você pode estender a classe StateTrigger para criar gatilhos personalizados para uma ampla variedade de cenários. Por exemplo, você pode criar um StateTrigger para disparar diferentes estados com base no tipo de entrada e, em seguida, aumentar as margens em torno de um controle quando o tipo de entrada for tocado. Ou crie um StateTrigger para aplicar estados diferentes com base na família de dispositivos em que o aplicativo é executado. Para obter exemplos de como criar gatilhos personalizados e usá-los para criar experiências otimizadas de interface do usuário a partir de uma única exibição XAML, consulte o Exemplo de gatilhos de estado.
Estados visuais e estilos
Você pode usar recursos de estilo em estados visuais para aplicar um conjunto de alterações de propriedade a vários controles. Para saber mais sobre como usar estilos, veja Controles de Estilo.
Neste XAML simplificado do exemplo de gatilhos de estado, um recurso de Estilo é aplicado a um Botão para ajustar o tamanho e as margens para a entrada por mouse ou toque. Para obter o código completo e a definição do gatilho de estado personalizado, consulte o Exemplo de gatilhos de estado.
<Page ... >
<Page.Resources>
<!-- Styles to be used for mouse vs. touch/pen hit targets -->
<Style x:Key="MouseStyle" TargetType="Rectangle">
<Setter Property="Margin" Value="5" />
<Setter Property="Height" Value="20" />
<Setter Property="Width" Value="20" />
</Style>
<Style x:Key="TouchPenStyle" TargetType="Rectangle">
<Setter Property="Margin" Value="15" />
<Setter Property="Height" Value="40" />
<Setter Property="Width" Value="40" />
</Style>
</Page.Resources>
<RelativePanel>
<!-- ... -->
<Button Content="Color Palette Button" x:Name="MenuButton">
<Button.Flyout>
<Flyout Placement="Bottom">
<RelativePanel>
<Rectangle Name="BlueRect" Fill="Blue"/>
<Rectangle Name="GreenRect" Fill="Green" RelativePanel.RightOf="BlueRect" />
<!-- ... -->
</RelativePanel>
</Flyout>
</Button.Flyout>
</Button>
<!-- ... -->
</RelativePanel>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="InputTypeStates">
<!-- Second set of VisualStates for building responsive UI optimized for input type.
Take a look at InputTypeTrigger.cs class in CustomTriggers folder to see how this is implemented. -->
<VisualState>
<VisualState.StateTriggers>
<!-- This trigger indicates that this VisualState is to be applied when MenuButton is invoked using a mouse. -->
<triggers:InputTypeTrigger TargetElement="{x:Bind MenuButton}" PointerType="Mouse" />
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="BlueRect.Style" Value="{StaticResource MouseStyle}" />
<Setter Target="GreenRect.Style" Value="{StaticResource MouseStyle}" />
<!-- ... -->
</VisualState.Setters>
</VisualState>
<VisualState>
<VisualState.StateTriggers>
<!-- Multiple trigger statements can be declared in the following way to imply OR usage.
For example, the following statements indicate that this VisualState is to be applied when MenuButton is invoked using Touch OR Pen.-->
<triggers:InputTypeTrigger TargetElement="{x:Bind MenuButton}" PointerType="Touch" />
<triggers:InputTypeTrigger TargetElement="{x:Bind MenuButton}" PointerType="Pen" />
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="BlueRect.Style" Value="{StaticResource TouchPenStyle}" />
<Setter Target="GreenRect.Style" Value="{StaticResource TouchPenStyle}" />
<!-- ... -->
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Page>
Tópicos relacionados
Windows developer