Archive

Posts Tagged ‘ICollectionView’

WPF: DataGrid – Parte 4

Olá amigos.

Nesse primeiro artigo de 2012 vou encerrar a série sobre DataGrid no WPF. Caso você não tenha visto meus artigos anteriores acessem:

Hoje vamos trabalhar com Grouping no DataGrid, ou veja, vamos agrupar os dados por um tipo de registro que selecionarmos.

Para esse exemplo crie duas tabelas em um banco de dados chamado PAIS e PILOTO, segue o script abaixo:


CREATE TABLE PAIS
(
   CD_PAIS NUMERIC(10) IDENTITY NOT NULL,
   NM_PAIS VARCHAR(50) NOT NULL
)
GO

CREATE TABLE PILOTO
(
   CD_PILOTO NUMERIC(10) IDENTITY NOT NULL,
   NM_PILOTO VARCHAR(50) NOT NULL,
   CD_PAIS   NUMERIC(10)
)
GO

ALTER TABLE PAIS ADD CONSTRAINT
   PAIS_PK PRIMARY KEY (CD_PAIS)
GO

ALTER TABLE PILOTO ADD CONSTRAINT
   PILOTO_PK PRIMARY KEY (CD_PILOTO)
GO

ALTER TABLE PILOTO ADD CONSTRAINT
   PILOTO_PAIS_FK FOREIGN KEY (CD_PAIS)
   REFERENCES PAIS (CD_PAIS)
GO

Com as tabelas criadas, vamos gerar os registros.

INSERT INTO PAIS VALUES ('BRASIL'), ('ALEMANHA'), ('FRANÇA'), ('GRÃ-BRETANHA'), ('FINLÂNDIA')
GO
INSERT INTO PILOTO VALUES ('Sebastian Vettel', 2),
                          ('Lewis Hamilton', 4),
                          ('Jenson Button', 4),
                          ('Nico Rosberg', 2),
                          ('Romain Grosjean', 3),
                          ('Kimi Raikkonen', 5),
                          ('Nico Hulkenberg', 2),
                          ('Felipe Massa', 1),
                          ('Bruno Senna', 1),
                          ('Heikki Kovalainen', 5),
                          ('Michael Schumacher', 2),
                          ('Jean-Eric Vergne', 3),
                          ('Charles Pic', 3),
                          ('Timo Glock', 2)
GO

Assim relacionamos os pilotos aos seus respectivos país. A ideia é agrupar os registros por País.

No Visual Studio crie um novo projeto do tipo WPF Application. Coloque na tela um DataGrid e um botão carregar, conforme imagem abaixo.

Crie uma coluna chamada Nome Piloto que irá receber a coluna NM_PILOTO do banco de dados conforme exemplo abaixo:

</pre>
<my:DataGrid.Columns>
 <my:DataGridTextColumn Binding="{Binding NM_PILOTO}" Header="Nome Piloto"></my:DataGridTextColumn>
 </my:DataGrid.Columns>
<pre>

Agora vamos criar a conexão com a base de dados, no evento on_click do botão carregar faça a conexão com o banco de dados e uma consulta simples conforme exemplo abaixo:

<pre>
DataSet dsConsulta = new DataSet();

            using (SqlConnection conn = new SqlConnection(@"Data Source=.;Initial Catalog=F1;Persist Security Info=True;User ID=sa;Password=f1;Connect Timeout=1800000000"))
            {
                StringBuilder stb = new StringBuilder();
                stb.Append("SELECT PL.NM_PILOTO,");
                stb.Append("       PA.NM_PAIS");
                stb.Append("  FROM PILOTO PL");
                stb.Append(" INNER JOIN PAIS PA");
                stb.Append("    ON PL.CD_PAIS = PA.CD_PAIS");
                conn.Open();

                SqlCommand cmd = new SqlCommand(stb.ToString(), conn);

                SqlDataAdapter sda = new SqlDataAdapter(cmd);

                sda.Fill(dsConsulta, "TABLE");
            }

Executando o botão carregar teremos os dados no grid conforme imagem abaixo:

Até agora não existe nenhuma novidade, agora vamos começar a desenvolver o agrupamento do nosso dados no DataGrid.

No evento on_click do botão carregar, vamos utilizar a interface ICollectionView que irá separar os dados de forma agrupada.

Primeiro passo será popular nosso objeto ICollectionView (com o nome de PilotoGrupo) com o resultado do DataSet.


ICollectionView PilotoGrupo = CollectionViewSource.GetDefaultView(dsConsulta.Tables[0]);

Veja que ao passar pelo PilotoGrupo (através do debug) , ele estará populado.

Agora vamos “falar” para nosso objeto PilotoGrupo que ele deve agrupar os registros pelo País. E também pegamos nosso objeto e setamos no datagrid


PilotoGrupo.GroupDescriptions.Add(new PropertyGroupDescription("NM_PAIS"));

this.dgPiloto.ItemsSource = PilotoGrupo;

Ao passar pelo PilotoGrupo (através do debug) , ele estará agrupado.

Destaquei na imagem que temos 5 groups principais (lembre-se do insert na tabela país onde adicionamos 5 países), e que no caso do Brasil ele já identificou que são dois registros (Felipe Massa e Bruno Senna).

Com isso temos nosso código C# preparado, porém o DataGrid ainda não está pronto. Precisamos criar a estrutura de agrupamento dentro do DataGrid.

Dentro do nosso DataGrid no código XAML vamos utilizar a tag GroupStyle, veja abaixo:

</pre>
<my:DataGrid.GroupStyle>
 <GroupStyle>
 <GroupStyle.ContainerStyle>
 <Style TargetType="{x:Type GroupItem}">
 <Setter Property="Template">
 <Setter.Value>
 <ControlTemplate TargetType="{x:Type GroupItem}">
 <Expander>
 <Expander.Header>
 <StackPanel Orientation="Horizontal">
 <TextBlock Text="{Binding Path=Name}" />
 <TextBlock Text="{Binding Path=ItemCount}" Margin="8,0,4,0"/>
 <TextBlock Text="Pilotos"/>
 </StackPanel>
 </Expander.Header>
 <ItemsPresenter />
 </Expander>
 </ControlTemplate>
 </Setter.Value>
 </Setter>
 </Style>
 </GroupStyle.ContainerStyle>
 </GroupStyle>
 </my:DataGrid.GroupStyle>
<pre>

Criamos um StackPanel na Horizontal e colocamos 3 TextBlock recebendo a propriedade Name da coleção (como vimos na imagem anterior), a propriedade ItemCount com a quantidade de item por grupo e o último apenas com a palavra Piloto.

Ao executar teremos o seguinte resultado.

Espero que tenham gostado e até a próxima.

Categorias:WPF Tags:, ,