Seções iMasters
Desenvolvimento

WPF – Usando o controle Grid

Já vimos outros
artigos sobre o Windows Presentation Foundation – WPF,
e, hoje falaremos sobre um controle
muito usado: o controle Grid.

Para os exemplos deste artigo usamos o Visual Basic 2010 Express Edition, onde no menu File -> New
Project
selecionamos o template WPF Application
e informamos o nome UsandoGrid. Na figura abaixo
vemos a solução criada:

O container Grid é o mais
familiar e poderoso controle WPF. A cada nova janela Windows
aberta no WPF temos um controle Grid incluído.

<Window x:Class="MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>

</Grid>
</Window>

Quando adicionado a uma janela (Window), ele consiste em um Grid de uma única célula. Linhas verticais
e horizontais adicionais podem ser adicionadas via código ou o
no descritor WPF. Você pode definir a propriedade ShowGridLines
para exibir uma grade linhas, e assim facilitar o posicionamento
dos elementos no Grid.

O Grid permite que você posicione
os controles dentro de células definidas pelo usuário.Os
controles colocados nas células mantêm uma margem fixa entre
duas ou mais bordas do controle ou da célula quando a janela for
redimensionada.

Dessa forma, o controle Grid pode ser
visto como um painel de layout que organiza seus controles filhos
em uma estrutura tabular de linhas e colunas. Sua funcionalidade
é semelhante à tabela HTML, porém mais flexível. Uma célula
pode conter vários controles, que podem ocupar várias células
e até mesmo se sobreporem umas as outras.

Um painel Grid pode ser usada para
criar interfaces de usuário complexas, onde precisamos colocar
vários elementos em uma tabela de layout de linhas e colunas.

O comportamento de redimensionamento
dos controles é definido pelas propriedades HorizontalAlignment
e VerticalAlignment que definem as âncoras. A
distância entre a âncora e a linha do grid é definida pela
margem do controle.

O elemento Grid em XAML representa
um painel Grid. O trecho de código a seguir cria um elemento
Grid e define seu plano de fundo, largura, altura, vertical e
propriedades de alinhamento horizontal:

<Grid
        Name="GridMacoratti"
        Background="LightGoldenrodYellow"
        Width="280" Height="220"
VerticalAlignment="Top" HorizontalAlignment="Center" >
</Grid>

Definindo
linhas e colunas

O controle Grid possui três
propriedades principais:

  • RowDefinitions – que representa uma coleção
    de itens RowDefinition;
  • ColumnDefinitions – que presenta uma coleção
    de itens ColumnDefinition;
  • ShowGridLines – que define se as linhas da
    grade de um painel são visíveis ou não;

O Grid tem por padrão uma linha e
uma coluna e para criar linhas e colunas adicionais você tem que
incluir itens RowDefinition a coleção RowDefinitions
e itens ColumnDefinition a coleção ColumnDefinitions.

No exemplo a seguir vamos definir um
Grid com 3 linhas e e colunas:

Podemos colocar qualquer controle
WPF no interior de um Grid usando suas propriedades Grid.Row
e Grid.Column que representam em qual
coluna e em qual linha o controle será colocado, sendo que os
valores das linhas e colunas começam em zero. (Isso
significa que, se existem 3 colunas em um Grid, a primeira seria a
coluna 0, a segunda a coluna 1 e a terceira a coluna 2)

Obs: Por padrão, linhas e
colunas ocupam a menor quantidade de espaço necessário para
acomodar o maior conteúdo em qualquer célula contida em uma
determinada linha ou coluna.

No próximo exemplo vamos incluir no
Grid que definimos acima um controle TextBox, em
uma célula do grid que esta na segunda linha e segunda coluna:

<TextBox Grid.Row="1" Grid.Column="1" Foreground="Blue" Text="Nome" Height="30" VerticalAlignment="Top" />

Grid.Row = 1 – indica a segunda
linha;
Grid.Column = 1 – indica a segunda coluna.

Nota: É possível posicionar com precisão elementos
filho em um Grid usando uma combinação da propriedade
Margin e da propriedade de alianhamento.

A seguir temos o mesmo exemplo onde
preenchemos cada célula do Grid via código XAML usando o
controle TextBlock:

 

<Window x:Class="MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525">
    <Grid Name="MacorattiGrid" Width="400" Background="LemonChiffon" ShowGridLines="True">
       <Grid.ColumnDefinitions>
            <ColumnDefinition />
            <ColumnDefinition />
            <ColumnDefinition />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="45" />
            <RowDefinition Height="45" />
            <RowDefinition Height="45" />
        </Grid.RowDefinitions>
      <TextBlock FontSize="14" FontWeight="Bold" Grid.Row="0" Grid.Column="0" Foreground="Blue" 
                   Text="Nome" Height="20" VerticalAlignment="Top"  />
        <TextBlock FontSize="14" FontWeight="Bold" Grid.Row="0" Grid.Column="1" Foreground="Blue" 
                   Text="Email" Height="20" VerticalAlignment="Top" />
        <TextBlock FontSize="14" FontWeight="Bold" Grid.Row="0" Grid.Column="2" Foreground="Blue" 
                   Text="Cidade" Height="20" VerticalAlignment="Top"/>
        <TextBlock FontSize="12" Grid.Row="1" Grid.Column="0">José Carlos Macoratti</TextBlock>
        <TextBlock FontSize="12" Grid.Row="1" Grid.Column="1">macoratti@yahoo.com</TextBlock>
        <TextBlock FontSize="12" Grid.Row="1" Grid.Column="2">Brasilia</TextBlock>
        <TextBlock FontSize="12" Grid.Row="2" Grid.Column="0">Janice Raquel</TextBlock>
        <TextBlock FontSize="12" Grid.Row="2" Grid.Column="1">janice@bol.com.br</TextBlock>
        <TextBlock FontSize="12" Grid.Row="2" Grid.Column="2">São Paulo</TextBlock>
    </Grid>
</Window>

Neste outro exemplo, temos
outra possibilidade de utilização do controle Grid:

<Window x:Class="MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525">
    <Grid Name="MacorattiGrid" Width="400" Background="LemonChiffon" ShowGridLines="True">
        <Grid VerticalAlignment="Top" HorizontalAlignment="Left" ShowGridLines="True" Width="250" Height="100">
            <Grid.ColumnDefinitions>
                <ColumnDefinition />
                <ColumnDefinition />
                <ColumnDefinition />
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition />
                <RowDefinition />
                <RowDefinition />
                <RowDefinition />
            </Grid.RowDefinitions>
            <TextBlock FontSize="20" Foreground="Green" FontWeight="Bold" Grid.ColumnSpan="3" Grid.Row="0">Vendas - 2011</TextBlock>
            <TextBlock FontSize="12" FontWeight="Bold" Grid.Row="1" Grid.Column="0">Janeiro</TextBlock>
            <TextBlock FontSize="12" FontWeight="Bold" Grid.Row="1" Grid.Column="1">Fevereiro</TextBlock>
            <TextBlock FontSize="12" FontWeight="Bold" Grid.Row="1" Grid.Column="2">Março</TextBlock>
            <TextBlock Grid.Row="2" Grid.Column="0">50000</TextBlock>
            <TextBlock Grid.Row="2" Grid.Column="1">100000</TextBlock>
            <TextBlock Grid.Row="2" Grid.Column="2">150000</TextBlock>
            <TextBlock FontSize="18" Foreground="Blue" FontWeight="Bold" Grid.ColumnSpan="3" Grid.Row="3">Vendas Total: 300000</TextBlock>
        </Grid>
    </Grid>
</Window>

Podemos criar um Grid em
tempo de execução via código usando a classe Grid. Abaixo
reproduzimos o mesmo Grid (definindo acima), onde o resultado da
execução do código do arquivo MainWindow.xaml.vb pode ser
visto abaixo:

Class MainWindow

    Private Sub MainWindow_Loaded(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs) Handles Me.Loaded
        'Cria um Grid como o raiz do elemento Panel
        Dim MacorattiGrid As New Grid()
        MacorattiGrid.Height = 100
        MacorattiGrid.Width = 250
        MacorattiGrid.ShowGridLines = True
        MacorattiGrid.HorizontalAlignment = Windows.HorizontalAlignment.Left
        MacorattiGrid.VerticalAlignment = Windows.VerticalAlignment.Top

        ' Define e Inclui Linhas e Colunas
        Dim colDef1 As New ColumnDefinition
        Dim colDef2 As New ColumnDefinition
        Dim colDef3 As New ColumnDefinition
        MacorattiGrid.ColumnDefinitions.Add(colDef1)
        MacorattiGrid.ColumnDefinitions.Add(colDef2)
        MacorattiGrid.ColumnDefinitions.Add(colDef3)

        Dim rowDef1 As New RowDefinition
        Dim rowDef2 As New RowDefinition
        Dim rowDef3 As New RowDefinition
        Dim rowDef4 As New RowDefinition
        MacorattiGrid.RowDefinitions.Add(rowDef1)
        MacorattiGrid.RowDefinitions.Add(rowDef2)
        MacorattiGrid.RowDefinitions.Add(rowDef3)
        MacorattiGrid.RowDefinitions.Add(rowDef4)

        Dim txt1 As New TextBlock
        txt1.Text = "Vendas - 2011"
        txt1.FontSize = 20
        txt1.FontWeight = FontWeights.Bold
        Grid.SetColumnSpan(txt1, 3)
        Grid.SetRow(txt1, 0)
        MacorattiGrid.Children.Add(txt1)

        Dim txt2 As New TextBlock
        txt2.Text = "Janeiro"
        txt2.FontSize = 12
        txt2.FontWeight = FontWeights.Bold
        Grid.SetRow(txt2, 1)
        Grid.SetColumn(txt2, 0)
        MacorattiGrid.Children.Add(txt2)

        Dim txt3 As New TextBlock
        txt3.Text = "Fevereiro"
        txt3.FontSize = 12
        txt3.FontWeight = FontWeights.Bold
        Grid.SetRow(txt3, 1)
        Grid.SetColumn(txt3, 1)
        MacorattiGrid.Children.Add(txt3)

        Dim txt4 As New TextBlock
        txt4.Text = "Março"
        txt4.FontSize = 12
        txt4.FontWeight = FontWeights.Bold
        Grid.SetRow(txt4, 1)
        Grid.SetColumn(txt4, 2)
        MacorattiGrid.Children.Add(txt4)

        Dim txt5 As New TextBlock
        txt5.Text = "50.000"
        Grid.SetRow(txt5, 2)
        Grid.SetColumn(txt5, 0)
        MacorattiGrid.Children.Add(txt5)

        Dim txt6 As New Controls.TextBlock
        txt6.Text = "100.000"
        Grid.SetRow(txt6, 2)
        Grid.SetColumn(txt6, 1)
        MacorattiGrid.Children.Add(txt6)

        Dim txt7 As New TextBlock
        txt7.Text = "150.000"
        Grid.SetRow(txt7, 2)
        Grid.SetColumn(txt7, 2)
        MacorattiGrid.Children.Add(txt7)

        ' Incluir o TextBlock final a célula do Grid
        Dim txt8 As New TextBlock
        txt8.FontSize = 14
        txt8.FontWeight = FontWeights.Bold
        txt8.Text = "Total Vendas: 300000"
        Grid.SetRow(txt8, 3)
        Grid.SetColumnSpan(txt8, 3)
        MacorattiGrid.Children.Add(txt8)

        Me.Content = MacorattiGrid

    End Sub
End Class

O tamanho da célula pode
ser definido como um valor absoluto de unidades lógicas, como um
valor percentual ou de forma automática:

  • Fixed
    – Tamanho fixo fixo de unidades lógicas (1/96 polegada).
  • Auto
    – Ocupa o espaço conforme a necessidade do controle
    contido
  • Star(*)
    – Ocupa o espaço conforme disponível distribuindo o
    espaço percentualmente. (Este recurso não não
    funciona se o tamanho da grade é calculado com base em
    seu conteúdo)

No exemplo a seguir temos
um Grid em um leiaute onde definimos 4 linhas e 2 colunas assim
defnidas:

  • Linhas : Primeira
    linha – Altura – Auto , Segunda linha – Altura – Auto,
    Terceira linha – Altura – * – percentual e Quarta linha –
    Altura = 28;
  • Colunas : Primeira
    coluna – Largura – Auto , Segunda linha – Largura = 300;

<Window x:Class="MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Usando o controle Grid" Height="350" Width="525">
    <Grid Name="MacorattiGrid" Width="400" Background="LightSalmon" ShowGridLines="True">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="*" />
            <RowDefinition Height="28" />
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto" />
            <ColumnDefinition Width="300" />
        </Grid.ColumnDefinitions>
        <Label Grid.Row="0" Grid.Column="0" Content="Nome:"/>
        <Label Grid.Row="1" Grid.Column="0" Content="E-Mail:"/>
        <Label Grid.Row="2" Grid.Column="0" Content="Assunto:"/>
        <TextBox Grid.Column="1" Grid.Row="0" Margin="3" />
        <TextBox Grid.Column="1" Grid.Row="1" Margin="3" />
        <TextBox Grid.Column="1" Grid.Row="2" Margin="3" />
        <Button Grid.Column="1" Grid.Row="3" HorizontalAlignment="Right" 
            MinWidth="80" Margin="3" Content="Enviar"  />
    </Grid>
</Window>

Usando
o controle GridSpliter para redimensionar o Grid

A WPF fornece um controle
chamado GridSplitter. Este controle é
adicionado como qualquer outro controle para uma célula da
grade. Ele permite que o usuário redimensione as linhas e
colunas do controle grid na direção horizontal e vertical.

No exemplo abaixo temos um
exemplo de utilização do controle GridSplitter:

<Window x:Class="MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Usando o controle Grid" Height="350" Width="525">
    <Grid Name="MacorattiGrid" Width="466" Background="LemonChiffon" ShowGridLines="True" 
          Canvas.Top="119" Canvas.Left="8" Height="200">
        <Grid.ColumnDefinitions>
            <ColumnDefinition />
            <ColumnDefinition />
            <ColumnDefinition />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="50*" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="50*" />
        </Grid.RowDefinitions>
       <GridSplitter 
               ResizeDirection="Rows"
                Grid.Column="0"
                Grid.ColumnSpan="10"
               Grid.Row="1" 
                Width="Auto"
                Height="3"
                HorizontalAlignment="Stretch"
                VerticalAlignment="Stretch"
                Margin="0"
                Background="Green"/>
    </Grid>
</Window>

Abaixo, vemos o projeto
acima em execução:


A melhor
maneira de alinhar um GridSplitter é coloca-lo
em sua própria coluna definida como auto. Dessa forma, você evita a sobreposição de células
adjacentes

Para
garantir que o GridSplitter altere o tamanho da
célula anterior e da seguinte, você tem que definir a
propriedade ResizeBehavior para PreviousAndNext.

Exemplo:

<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*"/>
        <ColumnDefinition Width="Auto"/>
        <ColumnDefinition Width="*"/>
    </Grid.ColumnDefinitions>
    <Label Content="Left" Grid.Column="0" />
    <GridSplitter HorizontalAlignment="Right" 
                  VerticalAlignment="Stretch" 
                  Grid.Column="1" ResizeBehavior="PreviousAndNext"
                  Width="5" Background="#FFBCBCBC"/>
    <Label Content="Right" Grid.Column="2" />
</Grid>

O divisor
do GridSplitter reconhece a direção para a
qual deve redirecionar de acordo com a relação entre a sua
altura e a largura mas você pode também configurar manualmente
a propriedade ResizeDirection para linhas ou
colunas:
Exemplo:

<GridSplitter
ResizeDirection="Columns"/>

Formatando
o Grid

A propriedade background
do Grid define as cores de fundo de uma grade. No exemplo a seguir definiremos um gradiente linear para desenhar o fundo do Grid.

Podemos usar a propriedade background
para definir uma imagem como fundo de uma grade. No exemplo a seguir
definiremos como fundo a imagem Garden.jpg e também a opacidade da
imagem:

E assim apresentei os principais
recursos do controle Grid e sua utilização. Existem mais
recursos que podem ser usados para incrementar o controle
ajustando-o à sua necessidade.

Simples assim! Eu sei é apenas WPF,
mas eu gosto…

Pegue o projeto completo
aqui: UsandoGrid.zip

Referências:

Mensagem do anunciante:

Torne-se um Parceiro de Software Intel®. Filie-se ao Intel® Developer Zone. Intel®Developer Zone

Qual a sua opinião?