C# – DataGridView – Salvando o conteúdo e realizando cálculos
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.
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













