Organizar os modos de exibição com o Grid
Suponha que você está criando uma página que exibe imagens em uma grade 7x5. É possível criar esta página com vários contêineres StackLayout
verticais e horizontais. Mas seria entediante codificar e poderia causar problemas de desempenho pro causa da memória e dos requisitos de processamento de vários painéis de layout. O painel de layout Grid
é uma opção melhor para interfaces do usuário que precisam de linhas e de colunas. Nesta unidade, você aprenderá como definir um Grid
e posicionar as exibições dentro de suas células.
O que é um Grid?
Um Grid
é um painel de layout que consiste em linhas e colunas. A ilustração a seguir mostra uma exibição conceitual de uma grade.
Coloque as exibições nas células criadas com base na interseção de linhas e colunas. Por exemplo, se você criar um Grid
que tenha três colunas e duas linhas, existem seis células disponíveis para exibições. As linhas e colunas podem ter diferentes tamanhos ou podem ser definidas para adaptar-se automaticamente ao tamanho dos filhos colocados dentro delas. As exibições filho podem ocupar uma única célula ou abranger várias delas. Essa flexibilidade torna o Grid
uma boa opção para o painel de layout raiz para muitos aplicativos.
Como especificar as linhas e as colunas de um Grid
Ao criar um Grid
, você pode definir cada linha e coluna individualmente. Esse sistema lhe dá controle total sobre a altura de cada linha e a largura de cada coluna. Todo Grid
tem uma coleção de objetos RowDefinition
e ColumnDefinition
que definem a forma da grade. Você preenche essas coleções com instâncias de RowDefinition
e ColumnDefinition
, cada uma representando uma linha ou coluna em sua interface do usuário.
Veja dois snippets de código que mostram as definições de classe para RowDefinition
e ColumnDefinition
:
public sealed class RowDefinition : ...
{
...
public GridLength Height { get; set; }
}
public sealed class ColumnDefinition : ...
{
...
public GridLength Width { get; set; }
}
Observe que RowDefinition
tem uma propriedade chamada Height
, e ColumnDefinition
tem uma propriedade chamada Width
. Use essas propriedades para definir a altura de uma linha e a largura de uma coluna, conforme descrito nas seções a seguir.
O que é GridLength?
O tipo de dados das propriedades Width
e Height
é GridLength
. Esse tipo contém duas propriedades: GridUnitType
e Value
. Veja um snippet de código que mostra uma parte da definição de tipo.
public struct GridLength
{
...
public GridUnitType GridUnitType { get; }
public double Value { get; }
}
É possível definir a propriedade GridUnitType
como um destes valores:
Absolute
Auto
Star
Vamos examinar mais detalhadamente cada um desses valores.
GridUnitType absoluto
Absolute
especifica que a linha ou coluna deve ter um tamanho fixo. Use a propriedade Value
para indicar o dimensionamento. Veja um exemplo que mostra como você definira a altura de uma linha para ter um tamanho fixo de 100
unidades de dispositivo em C#. Observe como você usa o construtor GridLength
, que aceita um valor numérico. Esse construtor define GridUnitType
como Absolute
automaticamente para você.
var row = new RowDefinition() { Height = new GridLength(100) };
Em XAML (Extensible Application Markup Language), você apenas fornece um valor numérico. O analisador XAML invoca um conversor de tipos para criar a instância GridLength
. Veja um exemplo que mostra a mesma coisa no XAML:
<RowDefinition Height="100" />
GridUnitType automático
Auto
dimensiona automaticamente a linha ou coluna para ajustar suas exibições filho. O Grid
verifica todas as exibições secundárias nessa linha ou coluna, seleciona a maior exibição e, em seguida, torna a linha ou coluna grande o suficiente para ajustar esse elemento filho. Quando você criar uma definição de linha no código, o valor numérico será ignorado. É possível usar qualquer valor. Veja um exemplo que mostra como você definira a altura de uma linha para ser automaticamente dimensionado em C#. Observe que escolhemos arbitrariamente 1
para o valor.
var row = new RowDefinition() { Height = new GridLength(1, GridUnitType.Auto) };
No XAML, use o valor Auto
. Veja um exemplo mostrando a mesma coisa em XAML.
<RowDefinition Height="Auto" />
GridUnitType em estrela
Star
oferece um dimensionamento proporcional. No dimensionamento proporcional, o espaço total disponível e a proporção solicitada por cada linha ou coluna determinam o tamanho. Nas conversas, as pessoas costumam chamar isso de dimensionamento em estrela em vez de dimensionamento proporcional.
Vamos percorrer o processo de usar o dimensionamento proporcional das linhas em uma grade.
Determine o espaço disponível: o
Grid
verifica todas as linhas queGrid
usam o dimensionamento em estrela. Ele adiciona a altura de todas essas linhas e subtrai esse total da altura doGrid
em si. Esse cálculo fornece a quantidade de espaço disponível para todas as linhas dimensionadas em estrela.Divida o espaço disponível: O
Grid
divide o espaço disponível entre todas as linhas dimensionadas em estrela com base na configuraçãoValue
para cada linha. Pense na propriedadeValue
como um multiplicador que determina a proporção entre todas as linhas definidas como dimensionadas em estrela. Por exemplo, se tivéssemos duas linhas dimensionadas em estrela, ambas com1
como o multiplicador, o espaço disponível seria dividido igualmente entre elas. Porém, se uma delas tivesse2
como o valor, ela receberia o dobro de espaço que a outra.
Veja um exemplo mostrando como você definiria a altura de uma linha como 2 Star
em C#:
var row = new RowDefinition() { Height = new GridLength(2, GridUnitType.Star) };
No XAML, use o símbolo *
para representar o dimensionamento em estrela. Combine o valor e o *
em uma única cadeia de caracteres e um conversor de tipo cria o GridLength
para você. Veja o mesmo exemplo em XAML.
<RowDefinition Height="2*" />
Coleções de grade
Após definir as linhas e colunas usando RowDefinition
e ColumnDefinition
, você pode adicioná-las a um Grid
. Você usa as propriedades da coleção RowDefinitions
e ColumnDefinitions
do Grid
. Preencher essas coleções normalmente é feito em XAML.
Este exemplo mostra como definir quatro linhas e adicioná-las a um Grid
usando a propriedade RowDefinitions
:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="100" />
<RowDefinition Height="Auto" />
<RowDefinition Height="1*" />
<RowDefinition Height="2*" />
</Grid.RowDefinitions>
...
</Grid>
Essa definição pode ser abreviada para:
<Grid RowDefinitions="100, Auto, 1*, 2*">
...
</Grid>
O XAML para definir colunas é análogo ao XAML anterior. Exceto que você usaria ColumnDefinitions
e definiria o Width
.
Em runtime, esse XAML produz um Grid
com quatro linhas. A primeira linha tem uma altura fixa de 100
unidades de dispositivo. A segunda linha tem a altura da exibição mais alta da linha. A terceira e a quarta linhas usam o dimensionamento em estrela, o que significa que elas pegam o espaço disponível restante e o dividem proporcionalmente com base no seu multiplicador Value
. Como a terceira linha é 1*
e a quarta linha é 2*
, a quarta linha tem o dobro da altura da terceira linha.
Tamanho padrão da linha e da coluna
O padrão de linhas e colunas é do tamanho 1*
. Por exemplo, examine o seguinte XAML.
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
...
</Grid>
Essa definição pode ser abreviada para:
<Grid RowDefinitions="*, *, *" ColumnDefinitions="*, *">
...
</Grid>
Como nenhuma das linhas ou colunas tem dimensionamentos especificados, 1*
é aplicado a todas elas. Em runtime, essa configuração cria um Grid
que é uniforme, o que significa que todas as linhas têm a mesma altura e todas as colunas têm a mesma largura.
Como adicionar exibições a um Grid
Quando adicionamos uma exibição a um Grid
, ela é adicionada a uma célula específica. As células são criadas nas posições de interseção de linhas e colunas. Para posicionar uma exibição em uma célula, você precisa saber o local da célula. Use uma combinação de um número de linha e de coluna para identificar uma célula.
Numeração de linha e de coluna
A numeração de linhas e de colunas começa em zero. A origem é o canto superior esquerdo. Veja uma ilustração que mostra a numeração de uma Grid
com quatro linhas e duas colunas.
Por exemplo, se desejarmos adicionar uma exibição à célula inferior direita, diremos que a posição da exibição será row 3 column 1
.
Adicionar uma exibição a um Grid usando propriedades anexadas
Você precisa de uma forma com a qual especificar o número da linha e da coluna de uma exibição quando a adicionamos a uma grade. Uma solução seria definir as propriedades Row
e Column
na classe base View
para poder especificar a posição na exibição diretamente. Essa técnica funcionaria, mas não é a abordagem mais eficiente. As exibições nem sempre estarão em um Grid
; portanto, às vezes, essas propriedades não seriam necessárias. Uma abordagem melhor é usar propriedades anexadas.
Uma propriedade anexada é uma propriedade definida em uma classe, mas definida em objetos de outros tipos.
Pense nas propriedades anexadas como uma coleção de pares chave-valor que faz parte de uma exibição. Ao adicionar um modo de exibição a um Grid
, você especifica a linha e a coluna. Usando propriedades anexadas, você pode adicionar um par chave-valor com a chave Grid.Row
e um valor que especifica o número da linha. Quando o Grid
estiver pronto para posicionar a exibição, ele verificará a coleção para ver se existe uma chave chamada Grid.Row
. Se existir, o Grid
utiliza o valor para posicionar a exibição.
Este exemplo mostra como criar um Grid
e adicionar uma exibição usando as propriedades anexadas:
<Grid RowDefinitions="*, *, *" ColumnDefinitions="*, *">
<BoxView Grid.Row="1" Grid.Column="0" Color="Navy" />
</Grid>
Neste exemplo, Grid.Row=1
e Grid.Column=0
são pares chave-valor que são adicionados a uma coleção interna do BoxView
. O Grid
utiliza esses valores para determinar em que posição a exibição deve ser posicionada. Veja qual será a aparência desta Grid
se você executar o aplicativo em um dispositivo.
Como fazer uma exibição abranger várias linhas ou colunas
Há mais duas propriedades anexadas que você deve considerar: Grid.RowSpan
e Grid.ColumnSpan
. Essas propriedades especificam quantas linhas ou colunas devem ser ocupadas pela exibição. Por exemplo, examine o seguinte XAML.
<Grid RowDefinitions="*, *, *" ColumnDefinitions="*, *">
<BoxView Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2" Color="Navy" />
</Grid>
Observe que este exemplo define ColumnSpan
como 2
. Essa exibição ocupa duas colunas iniciando em Column 0
. Veja qual será a aparência desta Grid
se você executar o aplicativo em um dispositivo.