Neste artigo eu vou mostrar como podemos salvar o conteúdo de um controle DataGridView e realizar cálculos que envolvam as células do controle.
Imagine que você tenha um formulário contendo um controle DataGridView, que está sendo usado para incluir informações de itens de um pedido:
Nesta interface o usuário poderá digitar diretamente no DataGridView, informando a descrição, a quantidade e o preço, sendo que o valor total é calculado automaticamente pela multiplicação das colunas, quantidade e preço. O total geral exibido em uma caixa de texto abaixo do DataGridView é uma somatória dos valores da coluna Total.
Ao final da entrada dos dados, o usuário poderá clicar no botão Salvar para salvar todos os valores informados no DataGridView.
Então, vamos ver como é que se faz isso.
Criando o projeto
Abra o Visual Studio 2012 Express for Windows desktop e clique em New Project. Escolha a linguagem Visual C# -> Windows e a o template Windows Forms Application informando o nome DataGridView_WF.
No formulário padrão form1.cs, inclua a partir da ToolBox os seguintes controles:
- 1 DataGridView – gdvItens
- 1 Button – btnSalvar
- 1 TextBox – txtTotal
Disponha os controles no formulário conforme o leiaute abaixo:
Criando o banco de dados e a tabela
Eu criei um banco de dados chamado Vendas.mdf no SQL Server Local DB e a tabela Itens que possui a seguinte estrutura:
A string de conexão do banco de dados está armazenada no arquivo App.Config:
<?xml version="1.0" encoding="utf-8" ?> <configuration> <startup> <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" /> </startup> <connectionStrings> <add name="VendasSQL" connectionString="Data Source=(localDB)\v11.0;Initial Catalog=Vendas;Integrated Security=True"/> </connectionStrings> </configuration>
No menu PROJECT, clique em Add Reference e selecione o namespace System.Configuration, que será usado para acessar o arquivo de configuração App.Config.
No formulário form1.cs declare os seguintes namespaces:
using System; using System.Configuration; using System.Data.SqlClient; using System.Windows.Forms;
Agora, no evento Load do formulário form1.cs, inclua o código abaixo que acessa o banco de dados Vendas e exibe os registros no controle DataGridView:
private void Form1_Load(object sender, EventArgs e) { try { DataTable oTable = new DataTable(); using (SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["VendasSQL"].ConnectionString)) { string sql = "Select * from Itens"; con.Open(); SqlCommand cmd = new SqlCommand(sql, con); cmd.CommandText = sql; cmd.CommandType = CommandType.Text; SqlDataReader oDataReader = cmd.ExecuteReader(CommandBehavior.CloseConnection); oTable.Load(oDataReader); gdvItens.DataSource = oTable; formataGridView(); } } catch (Exception ex) { MessageBox.Show(ex.ToString()); } }
A rotina formataGridView realiza uma formatação no controle DataGridView, permitindo uma exibição formata das colunas:
private void formataGridView() { var grade = gdvItens; grade.AutoGenerateColumns = false; grade.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.DisplayedCellsExceptHeaders; grade.ColumnHeadersBorderStyle = DataGridViewHeaderBorderStyle.Single; //altera a cor das linhas alternadas no grid grade.RowsDefaultCellStyle.BackColor = Color.White; grade.AlternatingRowsDefaultCellStyle.BackColor = Color.Cyan; //altera o nome das colunas grade.Columns[0].HeaderText = "Id"; grade.Columns[1].HeaderText = "Descrição"; grade.Columns[2].HeaderText = "Quantidade"; grade.Columns[3].HeaderText = "Preco"; grade.Columns[4].HeaderText = "Total"; grade.Columns[0].Width = 70; grade.Columns[1].Width = 150; //formata as colunas valor, vencimento e pagamento grade.Columns[3].DefaultCellStyle.Format = "c"; grade.Columns[4].DefaultCellStyle.Format = "c"; //seleciona a linha inteira grade.SelectionMode = DataGridViewSelectionMode.FullRowSelect; //não permite seleção de multiplas linhas grade.MultiSelect = false; // exibe nulos formatados //grade.DefaultCellStyle.NullValue = " - "; //permite que o texto maior que célula não seja truncado grade.DefaultCellStyle.WrapMode = DataGridViewTriState.True; //define o alinhamento à direita grade.Columns[3].DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight; grade.Columns[4].DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight; }
No evento Click, do botão Salvar, temos a chamada para a rotina SalvarDados():
private void btnSalvar_Click(object sender, EventArgs e) { SalvarDados(); }
O código da rotina é mostrado a seguir:
public void SalvarDados() { try { if (gdvItens.Rows.Count > 1) { for (int i = 0; i <= gdvItens.Rows.Count - 1; i++) { int col1 = Convert.ToInt32(gdvItens.Rows[i].Cells[0].Value); //id string col2 = gdvItens.Rows[i].Cells[1].Value.ToString(); //Descricao int col3 = Convert.ToInt32(gdvItens.Rows[i].Cells[2].Value); //Quantidade decimal col4 = Convert.ToDecimal(gdvItens.Rows[i].Cells[3].Value); //Preco decimal col5 = Convert.ToDecimal(gdvItens.Rows[i].Cells[4].Value); //Total using (SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["VendasSQL"].ConnectionString)) { string insert = "INSERT INTO Itens(Id,Descricao,Quantidade,Preco,Total) VALUES (@Codigo,@Descricao,@Quantidade,@Preco,@Total)"; con.Open(); SqlCommand cmd = new SqlCommand(insert, con); cmd.Parameters.AddWithValue("@Codigo", col1); cmd.Parameters.AddWithValue("@Descricao", col2); cmd.Parameters.AddWithValue("@Quantidade", col3); cmd.Parameters.AddWithValue("@Preco", col4); cmd.Parameters.AddWithValue("@Total", col5); cmd.ExecuteNonQuery(); con.Close(); } } } MessageBox.Show("Dados incluídos com sucesso !!", "Inclusão", MessageBoxButtons.OK, MessageBoxIcon.Information); } catch (Exception ex) { ex.Message.ToString(); } }
Este código verifica se existem linhas no controle DataGridView ( dvItens.Rows.Count > 1) e em caso positivo percorre cada uma das linhas atribuindo os valores das células à variáveis.
A seguir abriremos uma conexão com o banco de dados Vendas e definimos a instrução SQL INSERT/INTO, passando os parâmetros para o objeto Command. No método ExecuteNonQuery inclua os valores das células obtidos a partir do DataGridView na tabela Itens.
Para realizar o cálculo automático das colunas Quantidade e Preço vamos usar o evento CellEndEdit, definindo o código abaixo:
private void gdvItens_CellEndEdit(object sender, DataGridViewCellEventArgs e) { try { if (e.ColumnIndex == 3) { decimal cell1 = Convert.ToDecimal(gdvItens.CurrentRow.Cells[2].Value); decimal cell2 = Convert.ToDecimal(gdvItens.CurrentRow.Cells[3].Value); if (cell1.ToString() != "" && cell2.ToString() != "") { gdvItens.CurrentRow.Cells[4].Value = cell1 * cell2; } } decimal valorTotal = 0; string valor = ""; if (gdvItens.CurrentRow.Cells[4].Value != null) { valor = gdvItens.CurrentRow.Cells[4].Value.ToString(); if (!valor.Equals("")) { for (int i = 0; i <= gdvItens.RowCount - 1; i++) { if (gdvItens.Rows[i].Cells[4].Value != null) valorTotal += Convert.ToDecimal(gdvItens.Rows[i].Cells[4].Value); } if (valorTotal == 0) { MessageBox.Show("Nenhum registro encontrado"); } txtTotal.Text = valorTotal.ToString("C"); } } } catch (Exception ex) { MessageBox.Show(ex.ToString()); } }
No código verificamos se a coluna atual é a coluna Preco (e.ColumnIndex == 3). Em caso positivo, estamos calculando o valor da coluna total:
decimal cell1 = Convert.ToDecimal(gdvItens.CurrentRow.Cells[2].Value); decimal cell2 = Convert.ToDecimal(gdvItens.CurrentRow.Cells[3].Value); if (cell1.ToString() != "" && cell2.ToString() != "") { gdvItens.CurrentRow.Cells[4].Value = cell1 * cell2; }
A seguir verificamos se o valor da coluna Total não é nulo e estamos somando os valores desta coluna e exibindo no controle TextBox.(txtTotal).
Abaixo vemos o projeto em execução:
O objetivo deste artigo é mostrar algumas técnicas que podem ser uteis no dia a dia e que você pode adaptar para a sua situação.
Eu não estou encorajando você a usar essa implementação em seu projeto, visto que no exemplo eu tenho código de acesso a dados no formulário e não em uma camada de acesso a dados, como seria o correto.
Alerto também para o fato de que eu não estou realizando validações na entrada de dados, o que é obrigatório fazer em uma aplicação de produção.
Pegue o projeto completo aqui: DataGridView_WF.zip