En este post continúo el trabajo desde C# para modificar datos en mi tabla en SQL Server desde un DataGridView. En esta ocasión agrego una columna con botones al DataGridView para poner allí botones que permiten eliminar un registro o agregar uno nuevo. También escribo código que actualiza los datos de la tabla si cambia un valor en el DataGridView.
En este video te muestro cómo hacerlo:
Éstos son los campos que declaro en mi clase:
Y este es el Form_Load:
Y éste código se ejecuta cuando le dan clic al asterisco de la última fila del DataGridView (para dar de alta un nuevo registro):
Y éste es el método que se ejecuta cuando dan click sobre una celda (veo si presionó el botón de eliminar o guardar):
Éste es el método que elimina un registro:
Y éste agrega uno nuevo:
Esto corre cuando modifican el contenido de una celda del DataGridView:
Y, finalmente, éste es el método que actualiza los datos en la tabla:
Aquí les dejo el código completo (por si algo se me pasó):
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.SqlClient;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace _07_Recetario
{
public partial class frmIngredientes3 : Form
{
// Campos que uso
private BindingSource bindingSource;
private SqlDataAdapter dataAdapter;
private bool nuevoRegistro = false;
public frmIngredientes3()
{
InitializeComponent();
}
/// <summary>
/// Al cargar la ventana, lleno el DataGridView de datos y pongo las propeidades
/// necesarias para que pueda funcionar con botones en cada renglón.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void frmIngredientes3_Load(object sender, EventArgs e)
{
// Lleno la tabla y vinculo del bindingSource para poder relacionar datos aquí y en
// la base de datos (casi lo mismo que LeeDatos de frmIngredientes2)
SqlCommand comm = new SqlCommand("SELECT IdIngrediente,Nombre," +
"PrecioUnitario FROM Ingredientes ORDER BY Nombre", Global.conexion);
dataAdapter = new SqlDataAdapter(comm);
bindingSource = new BindingSource();
DataTable table = new DataTable();
SqlCommandBuilder commandBuilder = new SqlCommandBuilder(dataAdapter);
dataAdapter.Fill(table);
bindingSource.DataSource = table;
dataGridView1.DataSource = bindingSource;
// Que la columna de Id sea solo de lectura
dataGridView1.Columns[0].ReadOnly = true;
// Agrego una columna de botón al DataGridView
// (en este caso muestra un ícono de eliminar)
DataGridViewImageColumn btnElimina = new DataGridViewImageColumn();
btnElimina.Image = picElimina.Image;
btnElimina.Width = 20;
btnElimina.AutoSizeMode= DataGridViewAutoSizeColumnMode.AllCells;
dataGridView1.Columns.Add(btnElimina);
}
/// <summary>
/// Esto se ejecuta cuando da clic sobre el encabezado de una nueva fila o
/// hace click sobre elk símbolo del asterisco
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void RowHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e)
{
// Si va a agregar un registro...
if (e.RowIndex == dataGridView1.NewRowIndex)
{
// Dejo que se modifique el IdIngrediente
dataGridView1.Columns[0].ReadOnly = false;
// Indico que estoy agregando registro
nuevoRegistro = true;
// Pongo el ícono en la columna
dataGridView1.Rows[e.RowIndex].Cells[3].Value = picGuarda.Image;
}
}
/// <summary>
/// Se ejecuta cuando hacen click sobre la celda: quiero ver qué botón apretó
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void CellClick(object sender, DataGridViewCellEventArgs e)
{
// Si presionó la columna 3 (donde están los botones) y
// si no está en la primera fila y no está agregando un registro,
// quiere decir que presionó el botón de eliminar.
if (e.ColumnIndex == 3 && e.RowIndex > 0 && !nuevoRegistro)
{
// Le pregunto si lo desea borrar
DialogResult respuesta = MessageBox.Show("¿Deseas eliminar el registro",
"Ingredientes", MessageBoxButtons.OKCancel);
// Si sí, lo elimina
if (respuesta == DialogResult.OK)
{
// Obtengo el IDIngrediente
int id = int.Parse(dataGridView1.Rows[e.RowIndex].Cells[0].Value.ToString());
// Si se pudo eliminar de la tabla
if (EliminaIngrediente(id))
{
// Elimino la fila del DataGridView
dataGridView1.Rows.RemoveAt(e.RowIndex);
// Y mando mensaje
MessageBox.Show("Registro eliminado", "Ingredientes", MessageBoxButtons.OK,
MessageBoxIcon.Information);
}
else
{
// Si no se pudo, mando otro mensaje
MessageBox.Show("Error al eliminar el registro", "Ingredientes",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
// Si no fue el botón eliminar, veo si fue el de guardar
else if (e.ColumnIndex == 3 && nuevoRegistro)
{
int id = int.Parse(dataGridView1.Rows[e.RowIndex].Cells[0].Value.ToString());
String nombre = dataGridView1.Rows[e.RowIndex].Cells[1].Value.ToString();
float precio = -1;
// Reviso el precio porque puede ser un campo nulo
if (dataGridView1.Rows[e.RowIndex].Cells[2].Value.ToString() != "")
{
precio = float.Parse(dataGridView1.Rows[e.RowIndex].Cells[2].Value.ToString());
}
// Agrega el registro
if (AgregaIngrediente(id,nombre,precio))
{
// Ya no está agregando un registro
nuevoRegistro = false;
// Ya no puede modificar el ID
dataGridView1.Columns[0].ReadOnly = true;
// Regreso el botón de eliminar
dataGridView1.Rows[e.RowIndex].Cells[3].Value = picElimina.Image;
// Mando mensaje de que pudo agregar el regsitro con éxito
MessageBox.Show("Registro agregado", "Ingredientes", MessageBoxButtons.OK,
MessageBoxIcon.Information);
}
else
{
// Si no se pudo, mando otro mensaje
MessageBox.Show("Error al agregar el registro", "Ingredientes",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
/// <summary>
/// Se encarga de eliminar de la tabla Ingredientes el registro en cuestión
/// </summary>
/// <param name="id">El IDIngrediente</param>
/// <returns>true si se pudo eliminar, false si no</returns>
private bool EliminaIngrediente(int id)
{
try
{
SqlCommand comm = new SqlCommand("DELETE FROM Ingredientes WHERE IdIngrediente = " + id,
Global.conexion);
comm.ExecuteNonQuery();
return true;
}
catch (Exception)
{
return false;
}
}
/// <summary>
/// Agrega un ingrediente a la tabla
/// </summary>
/// <param name="ID">IdIngrediente (campo en la tabla)</param>
/// <param name="nombre">nombre del ingrediente</param>
/// <param name="precio">precio del ingrediente</param>
/// <returns>true si lo pudo agregar, false si no</returns>
private bool AgregaIngrediente(int id,String nombre,float precio)
{
try
{
// Si no tiene ID, pela
if (id <= 0)
{
return false;
}
else
{
// Armo instrucción SQL INSERT y lo ejecuto
string sql = "INSERT INTO Ingredientes (IdIngrediente,Nombre";
if (precio >= 0)
{
sql += ",PrecioUnitario) VALUES " +
"(" + id + ",'" + nombre + "'," + precio + ")";
}
else
{
sql += ") VALUES (" + id + ",'" + nombre + "')";
}
SqlCommand comm = new SqlCommand(sql, Global.conexion);
comm.ExecuteNonQuery();
return true;
}
}
catch (Exception)
{
return false;
}
}
/// <summary>
/// Cuando cambie el valor de una celda, que le permita guardar ese renglón/registro
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void CellValueChanged(object sender, DataGridViewCellEventArgs e)
{
// Si no está agregando un registro, hay que guardar/actualizar el registro
if (!nuevoRegistro)
{
// Tomo los datos de la celda modificada
int id = int.Parse(dataGridView1.Rows[e.RowIndex].Cells[0].Value.ToString());
String nombre = dataGridView1.Rows[e.RowIndex].Cells[1].Value.ToString();
float precio = -1;
// Reviso el precio porque puede ser un campo nulo
if (dataGridView1.Rows[e.RowIndex].Cells[2].Value.ToString() != "")
{
precio = float.Parse(dataGridView1.Rows[e.RowIndex].Cells[2].Value.ToString());
}
// Actualizo el registro, si se puede
if (ActualizaIngrediente(id,nombre,precio))
{
// Mando mensaje de que todo está bien
MessageBox.Show("Registro actualizado", "Ingredientes", MessageBoxButtons.OK,
MessageBoxIcon.Information);
}
else
{
// Mando mensaje de error si no se pudo
MessageBox.Show("Problemas al actualizar el registro", "Ingredientes",
MessageBoxButtons.OK,MessageBoxIcon.Error);
}
}
}
/// <summary>
/// Actualiza el registro en la base de datos
/// </summary>
/// <param name="id">IDProducto</param>
/// <param name="nombre">nombre del ingrediente</param>
/// <param name="precio">precio del ingrediente</param>
/// <returns>true si lo pudo actualizar, false si no</returns>
private bool ActualizaIngrediente(int id,String nombre,float precio)
{
try
{
string sql = "UPDATE Ingredientes SET Nombre = '" + nombre
+ "' WHERE IdIngrediente = " + id;
SqlCommand comm = new SqlCommand(sql, Global.conexion);
comm.ExecuteNonQuery();
if (precio >= 0)
{
sql = "UPDATE Ingredientes SET PrecioUnitario = " + precio
+ " WHERE IdIngrediente = " + id;
comm.CommandText = sql;
comm.ExecuteNonQuery();
}
return true;
}
catch (Exception)
{
return false;
}
}
}
}
Espero que les haya sido de utilidad esta explicación. ¡Hasta la próxima!