Archive

Archive for the ‘WPF’ Category

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

WPF: DataGrid – Parte 3

novembro 28, 2011 1 comentário

Nessa terceira parte do artigo vamos aprender a fazer uma coluna com link para um endereço da internet.

Para esse exemplo criei uma nova tela no Visual Studio com um grid e um botão carregar conforme imagem abaixo:

No evento do botão carregar crie o seguinte código:

private void btnCarregar_Click(object sender, RoutedEventArgs e)
        {
            DataSet dsConsulta = new DataSet();

            using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings[1].ConnectionString))
            {
                conn.Open();

                string strComando = "select VendorID, AccountNumber," +
                                    "       Name, " +
                                    "       PurchasingWebServiceURL," +
                                    "       CreditRating," +
                                    "       PreferredVendorStatus," +
                                    "       ActiveFlag" +
                                    "  from Purchasing.Vendor" +
                                    " where PurchasingWebServiceURL is not null";

                SqlCommand cmd = new SqlCommand(strComando, conn);

                SqlDataAdapter sda = new SqlDataAdapter(cmd);

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

            this.dgLink.DataContext = dsConsulta.Tables[0];
        }

As colunas de nosso grid devem ser criadas da seguinte forma:

<DataGrid AutoGenerateColumns="True" Height="299" HorizontalAlignment="Left" Margin="12,12,0,0" Name="dgLink" VerticalAlignment="Top" Width="466" ItemsSource="{Binding}">            <DataGrid.Columns>                <DataGridTextColumn Binding="{Binding Path=VendorID}" Header="Vendor ID" />                <DataGridTextColumn Binding="{Binding Path=AccountNumber}" Header="Account Number" />                <DataGridTextColumn Binding="{Binding Path=Name}" Header="Name" />                <DataGridHyperlinkColumn Header="Purchasing Web Service URL" Binding="{Binding PurchasingWebServiceURL}">                    <DataGridHyperlinkColumn.ElementStyle>                        <Style>                            <EventSetter Event="Hyperlink.Click" Handler="DG_Hyperlink_Click"/>                        </Style>                    </DataGridHyperlinkColumn.ElementStyle>                </DataGridHyperlinkColumn>            </DataGrid.Columns>        </DataGrid>

Criamos uma coluna do tipo DataGridHyperlinkColumn e definimos para ela um estilo. Dentro desse estilo definimos um evento Click e o evento (DG_Hyperlink_Click).
Agora vamos programar esse evento:

Hyperlink link = e.OriginalSource as Hyperlink;
Process.Start(link.NavigateUri.ToString());

Criamos um objeto Hyperlink que irá receber as informações do link no grid, em seguida chamamos esse endereço.  Se o endereço aponta um site que será aberta com o padrão web browser, se for uma pasta ela será aberta no explorer, se é um arquivo que será aberto com o aplicativo padrão associado a ele.

Execute o código e veja o resultado.

No próximo artigo vamos aprender novas funcionalidades o datagrid.

Até a próxima.

WPF: DataGrid – Parte 2

Na primeira parte do arquivo (caso não tenha lido acesse aqui) aprendemos como popular nosso DataGrid, especificar as colunas e os tipos de colunas. Como prometido vamos aprender a colocar uma imagem no DataGrid. Vamos continuar a utilizar a aplicação de exemplo do artigo anterior.

Primeiro passo é alterar nossa consulta anterior. Estamos utilizando nesse exemplo a base de dados do AdventureWorks. Nossa consulta irá partir da tabela Product até chegar na tabela Product Photo que contém a imagem do produto:

SELECT PRO.ProductID,
       PRO.Name,
       PRO.ProductNumber,
       PRO.color,
       IMG.ThumbNailPhoto
  FROM Production.Product PRO
 INNER JOIN Production.ProductProductPhoto PPR
    ON PPR.ProductID = PRO.ProductID
 INNER JOIN Production.ProductPhoto IMG
    ON PPR.ProductPhotoID = IMG.ProductPhotoID

Essa consulta irá trazer uma coluna chamada ThumbNailPhoto que possui uma imagem no formato binário.

Agora vamos alterar nosso código C# para acessar essa nova consulta, faça a alteração no evento click do botão Carregar;

private void btnCarregar_Click(object sender, RoutedEventArgs e)
        {
            DataSet dsConsulta = new DataSet();

            using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings[1].ConnectionString))
            {
                conn.Open();

                string strComando = "SELECT PRO.ProductID, " +
                                    "      PRO.Name, " +
                                    "      PRO.ProductNumber, " +
                                    "      PRO.color, " +
                                    "      IMG.ThumbNailPhoto " +
                                    " FROM Production.Product PRO " +
                                    "INNER JOIN Production.ProductProductPhoto PPR " +
                                    "   ON PPR.ProductID = PRO.ProductID " +
                                    "INNER JOIN Production.ProductPhoto IMG " +
                                    "   ON PPR.ProductPhotoID = IMG.ProductPhotoID";

                SqlCommand cmd = new SqlCommand(strComando, conn);

                SqlDataAdapter sda = new SqlDataAdapter(cmd);

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

            this.dgTeste.DataContext = dsConsulta.Tables[0];
        }

Agora é a parte interessante, vamos alterar o código XAML. No artigo anterior aprendemos sobre os tipos de colunas e um deles foi o DataGridTemplateColumn. Com esse tipo de coluna podemos definir qual objeto estará dentro da célula, pode ser um TextBlock, um CheckBox ou um componente Image que é o que vamos utilizar, veja o código abaixo:

                <DataGridTemplateColumn Header="Imagem" Width="SizeToCells" IsReadOnly="True">
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <Image Source="{Binding ThumbNailPhoto}" />
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>

Esse código deve ficar dentro da tag <DataGrid.Columns>. Criamos uma coluna do Tipo DataGridTemplateColumn. Dentro da coluna definimos a tag DataTemplate que onde definimos nosso componente. No componente Image definimos o Source onde setamos a imagem, no caso Binding (significa que vem da fonte de dados do DataGrid) e a coluna que contem a imagem.

Veja como ficou nosso exemplo:

Bem simples, não? Na próxima tarde desse artigo vamos aprender como utilizar a coluna DataGridHyperlinkColumn, a congelar colunas e outras funcionalidades.

Obrigado e até o próximo artigo.

WPF: DataGrid – Parte 1

WPF em suas primeiras versões não possuía um grid, porém na versão .NET 4.0 a Microsoft corrigiu essa “falha”. Nós últimos dias tive estudado sobre esse componente (estou desenvolvendo meu primeiro projeto em WPF) e vou compartilhas com vocês um pouco desse aprendizado.

Como de costume, gosto de explicar e ao mesmo tempo desenvolver o projeto, então abra o Visual Studio, crie um projeto WPF Application, no meu exemplo o nome ficou WPF_DataGrid. Na página MainWindows coloque um DataGrid e um botão, conforme abaixo:

Tela Iniciada

Para esse exemplo vou utilizar o banco de dados AdventureWorks que você acha de forma fácil para download na internet. No evento Click do botão carregar, faça uma conexão com a base do SQL Server e uma consulta na tabela Product conforme código abaixo:


        private void btnCarregar_Click(object sender, RoutedEventArgs e)
        {
            DataSet dsConsulta = new DataSet();

            using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings[1].ConnectionString))
            {
                conn.Open();

                SqlCommand cmd = new SqlCommand("SELECT ProductID, Name, ProductNumber, color FROM Production.Product", conn);

                SqlDataAdapter sda = new SqlDataAdapter(cmd);

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

Agora vamos ao nosso DataGrid. Coloquei o nome de dgTeste. No código XAML, localize o grid e coloque a opção ItemsSource=”{Binding}:

    <DataGrid AutoGenerateColumns="False" Height="287" HorizontalAlignment="Left" Margin="12,12,0,0" Name="dgTeste" VerticalAlignment="Top" Width="479" ItemsSource="{Binding}" />

É através do ItemsSource que informamos qual a fonte de dados o DataGrid ira acessar. Nesse exemplo a fonte de dados é dinâmica então apenas informamos que será um Binding (ligação de dados), poderíamos usar a opção Path para especificar a fonte (o que não faremos).

Em nosso DataGrid, altere a propriedade AutoGeneraterColumns para True.  e no final do nosso método carregar coloque:

this.dgTeste.DataContext = dsConsulta.Tables[0];

Execute o botão carregar e você terá o resultado abaixo:

Aprendemos como carregar o DataGrid de forma automática. Agora vamos supor, que mesmo minha consulta trazendo 4 colunas, queremos somente exibir 3 colunas e também queremos mudar o título da coluna. Nesse caso temos que criar as colunas na mão através do código XAML.

Primeiro passo é voltar a opção AutoGeneraterColumns para False.

Em seguida coloque uma Tag fechando o DataGrid e colocar a Tag de coluna, veja abaixo:

        <DataGrid AutoGenerateColumns="False" Height="287" HorizontalAlignment="Left"
                  Margin="12,12,0,0" Name="dgTeste" VerticalAlignment="Top" Width="479" ItemsSource="{Binding}">
            <DataGrid.Columns>

            </DataGrid.Columns>
        </DataGrid>

Agora temos que definir as colunas, podemos utilizar 5 opções:

  • DataGridCheckBoxColumn para valores booleanos
  • DataGridComboBoxColumn para valores enumeráveis
  • DataGridHyperlinkColumn para valores Uri
  • DataGridTemplateColumn para mostrar todos os tipos de dados, definindo o modelo de célula própria
  • DataGridTextColumn para mostrar valores de texto
No nosso exemplo, por hora vamos utilizar o tipo DataGridTextColumn, veja como vai ficar nosso DataGrid:

        <DataGrid AutoGenerateColumns="False" Height="287" HorizontalAlignment="Left"
                  Margin="12,12,0,0" Name="dgTeste" VerticalAlignment="Top" Width="479" ItemsSource="{Binding}">
            <DataGrid.Columns>
                <DataGridTextColumn Binding="{Binding Path=ProductID}" Header="Código Produto" />
                <DataGridTextColumn Binding="{Binding Path=Name}" Header="Nome" />
                <DataGridTextColumn Binding="{Binding Path=ProductNumber}" Header="Nº Produto" />
            </DataGrid.Columns>
        </DataGrid>

Criamos três colunas, onde no Binding informamos a qual Path cada coluna irá representar, no caso colocamos o nome das colunas que utilizamos em nossa consulta SQL. A propriedade Header é o nome que será exibido na coluna do DataGrid. Executando nossa aplicação veja como ficará:

Bem pessoal encerramos por aqui a primeira parte do artigo, salve a aplicação e aguardem o próximo artigo onde vamos aprender a colocar uma imagem no DataGrid e algumas outras propriedades disponíveis.

Até a próxima.

Categorias:WPF Tags:,