Principales respuestas
ComBox en DatagridView? C# - SQL Server

Pregunta
-
Hola
Tengo en SQL Server las tablas:
Estados:
int id_estado (PF)
varchar (50) descripcion
Ventas
int id_venta (PF)
datetime fecha
int id_estado (FK)
En un dategridviw en c# muestro Select id_venta, E.descripcion from Venta V inner join Estados E on E.id_estado = V.id_estado
Si quiero modificar el estado desde el datagridview directamente, me deja ponerle 1 o 2 o 3, pero no me deja ponerle estado "Vendido" o "Pendiente".
En vez de poner 1 o 2 o 3 para modificar el estado desde el datagridview, se puede desplegar un combobox con la descripcion de cada estado y poder modificar la venta ingresando la descripcion del estado en vez el id_estado?
A
Respuestas
-
Hola Yan Eric
Pido disculpas porque el código que te pasé está MAL casi todo, y te agradezco porque por este post tuyo y otro de hace un rato de Christian (problemas muy similares) aprendí algo muy importante, que lo investigué gracias a ustedes.
Te paso el código bien (lo probé con tu BD en mi SSMS) y luego te comento los detalles.
using System; using System.Data; using System.Data.SqlClient; using System.Windows.Forms; namespace WindowsFormsAppModifyByComboBox { public partial class Form1 : Form { private ComboBox combo; private SqlConnection conn; public Form1() { InitializeComponent(); } private void dataGridView1_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e) { combo = e.Control as ComboBox; combo.SelectionChangeCommitted -= new EventHandler(combo_SelectionChangeCommitted); combo.SelectionChangeCommitted += new EventHandler(combo_SelectionChangeCommitted); } private void combo_SelectionChangeCommitted(object sender, EventArgs e) { int id_estado = (int)combo.SelectedValue; string query2 = "UPDATE Ventas SET id_estado = " + id_estado.ToString() + " WHERE id_venta = " + dataGridView1.CurrentRow.Cells[0].Value.ToString(); conn.Open(); SqlCommand command2 = new SqlCommand(query2, conn); command2.ExecuteNonQuery(); conn.Close(); } private void Form1_Load(object sender, EventArgs e) { conn = new SqlConnection(@"Server=PABLOMARTY-PC\SQLEXPRESS;Database=VENTAS;Trusted_Connection=True;"); dataGridView1.AutoGenerateColumns = false; string query = "SELECT id_venta, id_estado FROM Ventas"; SqlCommand command = new SqlCommand(query, conn); DataTable table = new DataTable(); SqlDataAdapter adapter = new SqlDataAdapter(command); adapter.Fill(table); Id_Venta.DataGridView.DataSource = table; Id_Venta.DataPropertyName = "id_venta"; string query2 = "SELECT * FROM Estados"; SqlCommand command2 = new SqlCommand(query2, conn); DataTable table2 = new DataTable(); SqlDataAdapter adapter2 = new SqlDataAdapter(command2); adapter2.Fill(table2); Descripcion.DataGridView.DataSource = table; Descripcion.DataPropertyName = "id_estado"; Descripcion.DataSource = table2; Descripcion.ValueMember = "id_estado"; Descripcion.DisplayMember = "descripcion"; } } }
La consulta SQL de la tabla principal debería seleccionar los campos sin ningún JOIN, porque con sólo tener el valor de la FK obtenemos el string en la columna ComboBox.
Para eso, 1° cargamos los items con sus values a la columna:
Descripcion.DataSource = table2; // SELECT * FROM Estados
Descripción.ValueMember = "id_estado"; // el Id o PK de la tabla detalle
Descripcion.DisplayMember = "descripcion"; // el string o item
Lo anterior asigna datos en lo que es el ComboBox independientemente de las demás columnas
Ahora, para que "enganche" el valor de la FK de la tabla principal con el ValueMember del ComboBox y muestre el string correspondiente:
Descripcion.DataGridView.DataSource = table; // SELECT * FROM Ventas
Descripcion.DataPropertyName = "id_estado"; // la FK de la tabla principal
Con lo anterior se vincula los datos del DataGridView y su columna FK id_estado con el value del ComboBox para que coincidan y muestre el item correcto.
Si cambias la selección del ComboBox automáticamente se guarda (con la consulta y el SqlCommand) el nuevo valor de la FK (id_estado) de la tabla principal. En el método del evento EditingControlShowing (que se produce al manipular el ComboBox), se agrega el método del evento SelectionChangeCommitted del mismo, que una vez realizado el cambio ejecuta el SQL.
Gracias por ayudarme a aprender y compartir con los demás.
Saludos
Pablo
- Marcado como respuesta Eric_96 lunes, 12 de octubre de 2020 12:10
Todas las respuestas
-
-
Hola Yan Eric
Al fin lo pude resolver, enlazado a datos y todo. Este es el código. Habría que poner un DataGridView en el Form, con 2 columnas, una TextBox (llamada Id_Venta) y la otra ComboBox (llamada Descripcion). En mi ejemplo, los Estados , que se los paso a los Items de la columna ComboBox, son PEDIDO, PENDIENTE, y ENTREGADO. Podes probar con tus tablas, poniendo datos variados. El DataGridView te mostrará el id_venta y la descripción de cada venta, en las 2 columnas. Cuando modificas con el ComboBox un estado, automáticamente se hace un UPDATE del campo id_estado en la tabla Ventas, y al iniciar la aplicación otra vez ese cambio ya estará. Tendrías que asignar el método del EditingControlShowing en el cuadro de Propiedades.
using System; using System.Data; using System.Data.SqlClient; using System.Windows.Forms; namespace WindowsFormsAppModifyByComboBox { public partial class Form1 : Form { private ComboBox combo; private SqlConnection conn; public Form1() { InitializeComponent(); } private void dataGridView1_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e) { combo = e.Control as ComboBox; combo.SelectionChangeCommitted -= new EventHandler(combo_SelectionChangeCommitted); combo.SelectionChangeCommitted += new EventHandler(combo_SelectionChangeCommitted); } private void combo_SelectionChangeCommitted(object sender, EventArgs e) { string query1 = "SELECT id_estado FROM Estados WHERE descripcion = '" + combo.SelectedItem.ToString() + "'"; SqlCommand command1 = new SqlCommand(query1, conn); conn.Open(); SqlDataReader reader = command1.ExecuteReader(); reader.Read(); int id_estado = reader.GetInt32(0); reader.Close(); string query2 = "UPDATE Ventas SET id_estado = " + id_estado.ToString() + " WHERE id_venta = " + dataGridView1.CurrentRow.Cells[0].Value.ToString(); SqlCommand command2 = new SqlCommand(query2, conn); command2.ExecuteNonQuery(); conn.Close(); } private void Form1_Load(object sender, EventArgs e) { conn = new SqlConnection(@"Server=PABLOMARTY-PC\SQLEXPRESS;Database=VENTAS;Trusted_Connection=True;"); Descripcion.Items.AddRange("PEDIDO", "PENDIENTE", "ENTREGADO"); dataGridView1.AutoGenerateColumns = false; string query = "SELECT V.id_venta, V.id_estado, E.descripcion FROM Ventas V INNER JOIN Estados E ON V.id_estado = E.id_estado"; SqlCommand command = new SqlCommand(query, conn); DataTable table = new DataTable(); SqlDataAdapter adapter = new SqlDataAdapter(command); adapter.Fill(table); Id_Venta.DataGridView.DataSource = table; Id_Venta.DataPropertyName = "id_venta"; Descripcion.DataGridView.DataSource = table; Descripcion.DataPropertyName = "descripcion"; Descripcion.ValueMember = "id_estado"; Descripcion.DisplayMember = "descripcion"; } } }
Espero que te sea útil.
Saludos
Pablo
-
Hola Yan,
¿Alguna novedad sobre la consulta realizada?
Cualquier duda referente a productos Microsoft, puedes consultarnos. Es un gusto informarte.
Gracias por usar los foros de MSDN.
Eric Ruiz
____________________________
Por favor recuerde "Marcar como respuesta" las respuestas que hayan resuelto su problema, es una forma común de reconocer a aquellos que han ayudado, y hace que sea más fácil para los otros visitantes encontrar la solución más tarde.
Microsoft ofrece este servicio de forma gratuita, con la finalidad de ayudar a los usuarios y la ampliación de la base de datos de conocimientos relacionados con los productos y tecnologías de Microsoft.
Este contenido es proporcionado "tal cual" y no implica ninguna responsabilidad de parte de Microsoft.
-
Hola Yan Eric
Pido disculpas porque el código que te pasé está MAL casi todo, y te agradezco porque por este post tuyo y otro de hace un rato de Christian (problemas muy similares) aprendí algo muy importante, que lo investigué gracias a ustedes.
Te paso el código bien (lo probé con tu BD en mi SSMS) y luego te comento los detalles.
using System; using System.Data; using System.Data.SqlClient; using System.Windows.Forms; namespace WindowsFormsAppModifyByComboBox { public partial class Form1 : Form { private ComboBox combo; private SqlConnection conn; public Form1() { InitializeComponent(); } private void dataGridView1_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e) { combo = e.Control as ComboBox; combo.SelectionChangeCommitted -= new EventHandler(combo_SelectionChangeCommitted); combo.SelectionChangeCommitted += new EventHandler(combo_SelectionChangeCommitted); } private void combo_SelectionChangeCommitted(object sender, EventArgs e) { int id_estado = (int)combo.SelectedValue; string query2 = "UPDATE Ventas SET id_estado = " + id_estado.ToString() + " WHERE id_venta = " + dataGridView1.CurrentRow.Cells[0].Value.ToString(); conn.Open(); SqlCommand command2 = new SqlCommand(query2, conn); command2.ExecuteNonQuery(); conn.Close(); } private void Form1_Load(object sender, EventArgs e) { conn = new SqlConnection(@"Server=PABLOMARTY-PC\SQLEXPRESS;Database=VENTAS;Trusted_Connection=True;"); dataGridView1.AutoGenerateColumns = false; string query = "SELECT id_venta, id_estado FROM Ventas"; SqlCommand command = new SqlCommand(query, conn); DataTable table = new DataTable(); SqlDataAdapter adapter = new SqlDataAdapter(command); adapter.Fill(table); Id_Venta.DataGridView.DataSource = table; Id_Venta.DataPropertyName = "id_venta"; string query2 = "SELECT * FROM Estados"; SqlCommand command2 = new SqlCommand(query2, conn); DataTable table2 = new DataTable(); SqlDataAdapter adapter2 = new SqlDataAdapter(command2); adapter2.Fill(table2); Descripcion.DataGridView.DataSource = table; Descripcion.DataPropertyName = "id_estado"; Descripcion.DataSource = table2; Descripcion.ValueMember = "id_estado"; Descripcion.DisplayMember = "descripcion"; } } }
La consulta SQL de la tabla principal debería seleccionar los campos sin ningún JOIN, porque con sólo tener el valor de la FK obtenemos el string en la columna ComboBox.
Para eso, 1° cargamos los items con sus values a la columna:
Descripcion.DataSource = table2; // SELECT * FROM Estados
Descripción.ValueMember = "id_estado"; // el Id o PK de la tabla detalle
Descripcion.DisplayMember = "descripcion"; // el string o item
Lo anterior asigna datos en lo que es el ComboBox independientemente de las demás columnas
Ahora, para que "enganche" el valor de la FK de la tabla principal con el ValueMember del ComboBox y muestre el string correspondiente:
Descripcion.DataGridView.DataSource = table; // SELECT * FROM Ventas
Descripcion.DataPropertyName = "id_estado"; // la FK de la tabla principal
Con lo anterior se vincula los datos del DataGridView y su columna FK id_estado con el value del ComboBox para que coincidan y muestre el item correcto.
Si cambias la selección del ComboBox automáticamente se guarda (con la consulta y el SqlCommand) el nuevo valor de la FK (id_estado) de la tabla principal. En el método del evento EditingControlShowing (que se produce al manipular el ComboBox), se agrega el método del evento SelectionChangeCommitted del mismo, que una vez realizado el cambio ejecuta el SQL.
Gracias por ayudarme a aprender y compartir con los demás.
Saludos
Pablo
- Marcado como respuesta Eric_96 lunes, 12 de octubre de 2020 12:10