0 calificaciones0% encontró este documento útil (0 votos)
1K vistas
C# DataGridView
El documento describe cómo hacer que las celdas de texto en un DataGridView siempre estén en mayúsculas. Explica usar el evento EditingControlShowing para detectar cuando una celda entra en modo de edición y asignar un controlador de eventos KeyPress que convierte el carácter ingresado a mayúsculas. También describe declarar la celda en edición como una variable global para evitar problemas al asignar el controlador de eventos.
Descarga como DOCX, PDF, TXT o lee en línea desde Scribd
0 calificaciones0% encontró este documento útil (0 votos)
1K vistas
C# DataGridView
El documento describe cómo hacer que las celdas de texto en un DataGridView siempre estén en mayúsculas. Explica usar el evento EditingControlShowing para detectar cuando una celda entra en modo de edición y asignar un controlador de eventos KeyPress que convierte el carácter ingresado a mayúsculas. También describe declarar la celda en edición como una variable global para evitar problemas al asignar el controlador de eventos.
Descarga como DOCX, PDF, TXT o lee en línea desde Scribd
Está en la página 1/ 28
DataGridView
[DataGridView] Texto Celdas en Mayscula
Introduccin En algunos casos es necesario que la entrada de datos sea siempre en mayscula, lograr esto en un control Textbox es relativamente simple, ya que se dispone del evento KeyPress para detectar y convertir el valor ingresado. Pero que sucede si esto mismo se quiere aplicar a las celdas de un DataGridView, bien este articulo demuestra como poder lograrlo.
Usando el evento EditingControlShowing En el ejemplo se har uso del evento que permitir detecta cuando una celda entra en modo de edicin. Dentro del evento EditingControlShowing, se detecta si la columna que entro en modo de edicin corresponde a la que se quiere controlar. En este ejemplo solo la columna Descripcion ser afectada con el control en el input de datos. Es necesario remarcar que al momento de adjunta el evento KeyPress al objeto e.Control, (que ha sido casteado a DataGridViewTextBoxEditingControl, para su correcta utilizacin), el handler del evento se aplicara a todas las celdas de este mismo tipo. Tambin a las de las columnas que no se quiere aplicar el control de maysculas, en este caso la de Cuenta. Es por eso que en el evento KeyPress tambin se control la columna que esta activa en ese momento. El handler del evento queda adjunto aun cuando se sale de modo edicin. La utilizacin de la primer lnea que quita el hadler al entrar en edicin: dText.KeyPress -= new KeyPressEventHandler(dText_KeyPress); Solo sirve para que se adjunte un nico evento, ya que sino estuviera se adjuntaran una detrs de otro producindose mltiples llamadas al evento KeyPress. [C#] 01.private void dataGridView1_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e) 02.{ 03.int columnIndex = dataGridView1.CurrentCell.ColumnIndex; 04. 05.if (dataGridView1.Columns[columnIndex].Name == "Descripcion") 06.{ 07.DataGridViewTextBoxEditingControl dText = (DataGridViewTextBoxEditingControl)e.Control; 08. 09.dText.KeyPress -= new KeyPressEventHandler(dText_KeyPress); 10.dText.KeyPress += new KeyPressEventHandler(dText_KeyPress); 11.} 12.} 13. 14.void dText_KeyPress(object sender, KeyPressEventArgs e) 15.{ 16.int columnIndex = dataGridView1.CurrentCell.ColumnIndex; 17. 18.if (dataGridView1.Columns[columnIndex].Name == "Descripcion") 19.{ 20.e.KeyChar = char.ToUpper(e.KeyChar); 21.} 22.} Resolucin del problema en al asignacin del evento El problema comentado anteriormente podras resolverse fcilmente con solo declarar la variable que contendr la celda en edicin de forma global al evento. De esta forma se podras hacer uso del evento que detecta cuando una celda ha dejado de editarse, removiendo el handler del evento. Ahora el evento KeyPress no controla que columna se esta editando, esto solo se hace cuando se entra o sale del modo edicin de la celda. [C#] 01.DataGridViewTextBoxEditingControl dText = null; 02. 03.private void dataGridView1_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e) 04.{ 05.int columnIndex = dataGridView1.CurrentCell.ColumnIndex; 06. 07.if (dataGridView1.Columns[columnIndex].Name == "Descripcion") 08.{ 09.dText = (DataGridViewTextBoxEditingControl)e.Control; 10. 11.dText.KeyPress += new KeyPressEventHandler(dText_KeyPress); 12.} 13.} 14. 15.private void dataGridView1_CellEndEdit(object sender, DataGridViewCellEventArgs e) 16.{ 17.int columnIndex = dataGridView1.CurrentCell.ColumnIndex; 18. 19.if (dataGridView1.Columns[columnIndex].Name == "Descripcion") 20.{ 21.dText.KeyPress -= new KeyPressEventHandler(dText_KeyPress); 22.} 23.} 24. 25.void dText_KeyPress(object sender, KeyPressEventArgs e) 26.{ 27.e.KeyChar = char.ToUpper(e.KeyChar); 28.}
C# - [DataGridView] DataGridViewComboBoxColumn Variar contenido del combobox respecto a la fila
Introduccin El objetivo del artculo es demostrar algunos problemas que pueden surgir cuando se necesita que el ComboBox ubicado en las celdas del DataGridView, vare su contenido de acuerdo al registro que se visualiza.Para demostrar el problema, se ha definido un dominio del ejemplo intentara cargar una grilla de sucursales, de los cuales mostraran el listado de los telfonos disponibles.Por supuesto para cada sucursal los telfonos disponibles varan, por lo tanto definir el contenido del combo como una nica lista no es posible.
Carga del contenido variable en ComboBox En el evento Load del formulario se procede a la carga de las sucursales, e inmediatamente despus de esta operacin se invoca a un mtodo creado con el fin de la carga de los combos de cada registro de a grilla.Este mtodo recorre en un ciclo cada registro, toma el id de la sucursal que se encuentra en la celda del registro actual, y tambin toma la celda que representa el combo.Con las anteriores dos selecciones procede a realizar una consulta a los datos y cargar en el combo los telfonos de esa sucursal.
01.private void frmSucursales_Load(object sender, EventArgs e) 02.{ 03.SucursalesEntities sucursalesContext = new SucursalesEntities(); 04. 05.dgvScursales.AutoGenerateColumns=false; 06.dgvScursales.DataSource = sucursalesContext.Sucursales; 07. 08.// 09.// Luego de bindear la grilla, cargo el contenido de cada fila 10.// en el combo de telefonos para cada sucursal 11.// 12.LoadGrillaComboBoxTelefonos(); 13. 14.} 15. 16.private void LoadGrillaComboBoxTelefonos() 17.{ 18.foreach (DataGridViewRow row in dgvScursales.Rows) 19.{ 20.int idSucursal = Convert.ToInt32(row.Cells["IdSucursal"].Value); 21. 22.DataGridViewComboBoxCell comboboxCell = row.Cells["Telefonos"] asDataGridViewComboBoxCell; 23. 24.SucursalesEntities sucursalesContext = new SucursalesEntities(); 25. 26.comboboxCell.DataSource = sucursalesContext.Telefonos.Where(x => x.IdSucursal == idSucursal); 27.comboboxCell.ValueMember = "Id"; 28.comboboxCell.DisplayMember = "Numero"; 29. 30.} 31.}
Algunos Comentarios Durante la realizacin del ejemplo se realizaron varias pruebas, con algunos eventos que se adaptaran a la situacin y evitaran tener que recorrer en un foreach cada registro del DataGridView. Despus de investigar un poco los nicos dos eventos que se adaptaran a este caso serian el RowsAdded y el CellFormatting, pero ambos trajeron problemas, lo que impidi su uso. El CellFormatting, tiene como problema que se ejecuta contantemente, ya que es lanzado al redibujar la celda, y como esta operacin requiere la consulta a los datos, generaba un efecto de bloqueo en la pantalla, el cual no es deseado. El RowsAdded, si bien se ejecuta por cada fila agregada en la operacin de bindeo de los datos, no haba forma interna en el evento de detectar que fila se estaba agregando, ya que el argumento del evento e.RowIndex o e.RowCount, no devuelven un valor correcto. Como conclusin se dejo de lado los eventos y se hizo uso del foreach, implementado esto en un mtodo, cuya utilizacin se realiza luego que se bindearon los datos en el control.
C# - [DataGridView] Pasar Registros entre Grillas
Introduccin
El articulo explica de que forma se puede seleccionar registros en el control DataGridView y pasarlos a otro, representando este la seleccin de las filas por el usuario. En uno de los DataGridView se listaran productos, y por medio de un checkbox en cada fila, se podr seleccionar que tems se desean seleccionar. Botones que indican la direccin sern los encargados de ejecutar la opcin de pasaje. El diseo de la interfaz puede apreciarse en esta imagen:
Carga de la lista de productos
Para esta operacin se requerir la ayuda del DataSet tipado el cual define la estructura de la entidad, pero ser responsabilidad de la clase con sufijo DAL, la que cargara la informacin, proveniente de la base de datos. 01.private void frmPedidos_Load(object sender, EventArgs e) 02.{ 03.// 04.// Se recupera los datos de los productos desde la tabla 05.// 06.dtoProductos datos = ProductoDAL.ProductosGetAll(); 07. 08.// 09.// Se bindean los datos a la grilla 10.// 11.dgvProductos.AutoGenerateColumns = false; 12.dgvProductos.DataSource = datos; 13.dgvProductos.DataMember = "Productos"; 14. 15.} Seleccin de un tem en la grilla de origen
Hay que destacar que la operacin sobre un DataGridView difiere si esta se encuentra previamente enlazada a datos, o no. En esta primera operacin implica la seccin de un producto que pasara a una lista no enlazada a datos, por lo tanto se podr hacer uso de mtodo Add() de la coleccin de Rows de la grilla. 01.private void btnSeleccionar_Click(object sender, EventArgs e) 02.{ 03.// 04.// Se define una lista temporal de registro seleccionados 05.// 06.List<DataGridViewRow> rowSelected = new List<DataGridViewRow>(); 07. 08.// 09.// Se recorre ca registro de la grilla de origen 10.// 11.foreach (DataGridViewRow row in dgvProductos.Rows) 12.{ 13.// 14.// Se recupera el campo que representa el checkbox, y se valida la seleccion 15.// agregandola a la lista temporal 16.// 17.DataGridViewCheckBoxCell cellSelecion = row.Cells["Seleccion"] asDataGridViewCheckBoxCell; 18. 19.if Convert.ToBoolean(cellSelecion.Value)) 20.{ 21.rowSelected.Add(row); 22.} 23.} 24. 25.// 26.// Se agrega el item seleccionado a la grilla de destino 27.// eliminando la fila de la grilla original 28.// 29.foreach DataGridViewRow row in rowSelected) 30.{ 31.dgvSeleccion.Rows.Add(new object[] {false, 32.row.Cells["Descripcion"].Value, 33.row.Cells["PrecioUnitario"].Value, 34.row.Cells["UnidadMedida"].Value}); 35. 36.dgvProductos.Rows.Remove(row); 37.} 38. 39.} Hay que remarcar tambin que el uso de la lista temporal no es un capricho, sino que es necesaria ya que mientras se recorre una lista por medio de la instruccin for each, no pueden removerse elementos. Por esta razn es que en una operacin siguiente se recorre la seleccin y all si se procede a incluye los tems en al grilla de destino y quitarla de la original. Este punto lo he explicado con mas detalle siguiente articulo: Eliminar tems en una lista
Seleccin de un tem en la grilla de destino
Ahora le toca el turno a la operacin contraria, y aqu hay un punto que ya se mencion en el paso previo, la lista de origen est vinculada a datos de productos con lo cual usar el Rows.Add() no es posible. Para esta operacin se agregaran los datos directo en el origen, en este caso el datatable, que se ha creado dentro del DataSet tipado.
01.private void btnQuitar_Click(object sender, EventArgs e) 02.{ 03.// 04.// Se define una lista temporal de registro seleccionados 05.// 06.List<DataGridViewRow> rowSelected = new List<DataGridViewRow>(); 07. 08.// 09.// Se recorre cada fila de la grilla de seleccion y se determian que registros estan checkeados 10.// 11.foreach (DataGridViewRow row in dgvSeleccion.Rows) 12.{ 13.DataGridViewCheckBoxCell cellSelecion = row.Cells["SeleccionSel"] asDataGridViewCheckBoxCell; 14. 15.if (Convert.ToBoolean(cellSelecion.Value)) 16.{ 17.rowSelected.Add(row); 18.} 19.} 20. 21.// 22.// Se valida si hay algun registro por eliminar 23.// 24.if (rowSelected.Count > 0) 25.{ 26.// 27.// Se recupera el origen de datos que tiene asignada la grilla de productos 28.// 29.dtoProductos datos = dgvProductos.DataSource as dtoProductos; 30. 31.// 32.// Se recorre cada item seleccionado y se arma programaticamente la fila del DataTable 33.// se elimina el registro de la grilla de selecciones 34.// 35.foreach (DataGridViewRow row in rowSelected) 36.{ 37. 38.dtoProductos.ProductosRow productoRow = datos.Productos.NewProductosRow(); 39. 40.productoRow.Descripcion = Convert.ToString(row.Cells["DescripcionSel"].Value); 41.productoRow.PrecioUnitario = Convert.ToDecimal(row.Cells["PrecioUnitarioSel"].Value); 42.productoRow.UnidadMedida = Convert.ToString(row.Cells["UnidadMedidaSel"].Value); 43.datos.Productos.Rows.Add(productoRow); 44. 45.dgvSeleccion.Rows.Remove(row); 46.} 47. 48.// 49.// Se binden los datos nuevamente, pero ahora con los nuevos registros 50.// agregados del paso anterior 51.// 52.dgvProductos.AutoGenerateColumns = false; 53.dgvProductos.DataSource = datos; 54.dgvProductos.DataMember = "Productos"; 55.} 56.} Es necesario analizar como toma los datos originales convirtiendo el contenido de DataSource de la grilla, en este caso a dtoProductos, ya que este es el tipo de datos utilizado en al carga original. Se toman los datos originales, se procede a la creacin de cada row de forma programtica, asignando el valor a cada campo, por ultimo se vuelve a bindear la grilla.
C# - [DataGridView] Uso del CheckBox - DataGridViewCheckBoxColumn
Introduccin El articulo intentara mostrar las algunas forma en que se puede utilizar el checkbox en un control DataGridView. Detectar el cambio en la seleccin Para realizar la tarea se har uso de dos eventos que pueden ser igual de tiles, el CellValueChange y el CellContentClick De forma estndar el CellValueChange, se deparar a seleccionar el check de la celda y quitar el foco de la misma, saliendo del modo de edicin. Pero este no ejecuta la accin en el mismo instante en que se origina, sino que hay que salir de la edicin de la celda para que el evento ocurra. 01.private void dataGridView1_CellValueChanged(object sender, DataGridViewCellEventArgs e) 02.{ 03.// 04.// Solo se trabaja ante los cambios en la columan de los checkbox 05.// 06.if (dataGridView1.Columns[e.ColumnIndex].Name == "Seleccion") { 07.// 08.// Se toma la fila seleccionada 09.// 10.DataGridViewRow row = dataGridView1.Rows[e.RowIndex]; 11. 12.// 13.// Se selecciona la celda del checkbox 14.// 15.DataGridViewCheckBoxCell cellSelecion = row.Cells["Seleccion"] asDataGridViewCheckBoxCell; 16. 17.// 18.// Se valida si esta checkeada 19.// 20.if (Convert.ToBoolean(cellSelecion.Value)) { 21. 22.string mensaje = string.Format("Evento CellValueChanged.\n\nSe ha seccionado, \nDescripcion: '{0}', \nPrecio Unitario: '{1}', \nMedida: '{2}'", 23.row.Cells["Descripcion"].Value, 24.row.Cells["PrecioUnitario"].Value, 25.row.Cells["UnidadMedida"].Value); 26. 27.MessageBox.Show(mensaje, "", MessageBoxButtons.OK, MessageBoxIcon.Information); 28. 29.} 30. 31.} 32. 33.} Con respecto al CellContentClick, que si ejecuta la accin en el mismo momento en que el usuario marca, o desmarca, el checkbox, pero me encontr que solo devolva null en la propiedad Value de la celda. 01.private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e) 02.{ 03.// 04.// Detecta si se ha seleccionado el header de la grilla 05.// 06.if (e.RowIndex == -1) 07.return; 08. 09.if (dataGridView1.Columns[e.ColumnIndex].Name == "Seleccion") 10.{ 11. 12.// 13.// Se toma la fila seleccionada 14.// 15.DataGridViewRow row = dataGridView1.Rows[e.RowIndex]; 16. 17.// 18.// Se selecciona la celda del checkbox 19.// 20.DataGridViewCheckBoxCell cellSelecion = row.Cells["Seleccion"] asDataGridViewCheckBoxCell; 21. 22. 23.if (Convert.ToBoolean(cellSelecion.Value)) 24.{ 25. 26.string mensaje = string.Format("Evento CellContentClick.\n\nSe ha seccionado, \nDescripcion: '{0}', \nPrecio Unitario: '{1}', \nMedida: '{2}'", 27.row.Cells["Descripcion"].Value, 28.row.Cells["PrecioUnitario"].Value, 29.row.Cells["UnidadMedida"].Value); 30. 31.MessageBox.Show(mensaje, "", MessageBoxButtons.OK, MessageBoxIcon.Information); 32. 33.} 34.else 35.{ 36.string mensaje = string.Format("Evento CellContentClick.\n\nSe ha quitado la seleccion, \nDescripcion: '{0}', \nPrecio Unitario: '{1}', \nMedida: '{2}'", 37.row.Cells["Descripcion"].Value, 38.row.Cells["PrecioUnitario"].Value, 39.row.Cells["UnidadMedida"].Value); 40. 41.MessageBox.Show(mensaje, "", MessageBoxButtons.OK, MessageBoxIcon.Information); 42. 43.} 44.} 45.} Tambin se ha intentado hacer uso del evento EditingControlShowing, el cual permitira detectar la seleccin en el mismo momento que el usuario realiza la accin, pero esto no fue posible ya que este tipo de columna no provoca el evento necesario para tomar el control CheckBox y asignar el evento SelectedIndexChanged. Ante este problema con los eventos, y notar que ninguno responde como debera, se encontr un mtodo que resolvi todos los problemas de un solo golpe, se trata del CommitEdit 1.private void dataGridView1_CurrentCellDirtyStateChanged(object sender, EventArgs e) 2.{ 3.if (dataGridView1.IsCurrentCellDirty) 4.{ 5.dataGridView1.CommitEdit(DataGridViewDataErrorContexts.Commit); 6.} 7.} En el evento CurrentCellDirtyStateChanged, se detecta si la grilla esta con algn cambio pendiente, y en caso de estarlo se hace un Commit del mismo para reflejar el valor en los eventos que lo usaran. Esto arregla los dos problemas detectados anteriormente: - se lanza el evento CellValueChanged, sin tener que quitar el foco de la celda - ya no se recibe el null en el Value de la celda, en el evento CellContentClick
Aplicar formato a la seleccin Teniendo en cuenta lo contado en la seccin anterior, aplicar un formato a la fila seleccionada no debera ser un misterio. 01.private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e) 02.{ 03.// 04.// Detecta si se ha seleccionado el header de la grilla 05.// 06.if (e.RowIndex == -1) 07.return; 08. 09.if (dataGridView1.Columns[e.ColumnIndex].Name == "Seleccion") 10.{ 11. 12.// 13.// Se toma la fila seleccionada 14.// 15.DataGridViewRow row = dataGridView1.Rows[e.RowIndex]; 16. 17.// 18.// Se selecciona la celda del checkbox 19.// 20.DataGridViewCheckBoxCell cellSelecion = row.Cells["Seleccion"] asDataGridViewCheckBoxCell; 21. 22.if (Convert.ToBoolean(cellSelecion.Value)) 23.row.DefaultCellStyle.BackColor = Color.Green; 24.else 25.row.DefaultCellStyle.BackColor = Color.White; 26. 27.} 28.} 29. 30.private void dataGridView1_CurrentCellDirtyStateChanged(object sender, EventArgs e) 31.{ 32.if (dataGridView1.IsCurrentCellDirty) 33.{ 34.dataGridView1.CommitEdit(DataGridViewDataErrorContexts.Commit); 35.} 36.} Simplemente ante la deteccin de la seleccin del usuario se cambia el color de la fila usando el DefaultCellStyle.BackColor.
C# - [Winforms] Seleccionar Fila con ENTER DataGridView y ListView
Introduccin Este articulo es mostrara una alternativa de como se puede detectar la presin de una tecla (en este caso el ENTER) en un control determinado, pudiendo as trabajar con la seleccin. En el ejemplo se trabajar con dos controles, el DataGridView y un ListView. Bsicamente la tcnica para ambos ejemplos ser similar, todo el trabajo se realizara en el mtodo ProcessCmdKey del formulario, (el cual es una sobrecarga), permitiendo atrapar la teclas pulsadas en el formulario, en este adems se podras validar que control esta activo en ese momento y en caso de ser el que resulta til, procede a trabajar con la seleccin. Para ambos ejemplo se permitir optar (mediante radiobuttons) si la seleccin del tem en la lista se mostrar en un mensaje, o ser desplegado en otra ventana (formulario).
DataGridView - Seleccin de la fila Como haba comentado todo el trabajo esta en la funcin: [C#] 01.protected override bool ProcessCmdKey(ref System.Windows.Forms.Message msg, System.Windows.Forms.Keys keyData) 02.{ 03.// 04.// Si el control DataGridView no tiene el foco, 05.// se abandonamos el procedimiento, llamando al metodo base 06.// 07.if ((!dataGridView1.Focused)) 08.return base.ProcessCmdKey(ref msg, keyData); 09. 10.// 11.// Si la tecla presionada es distinta al ENTER, 12.// se abandonamos el procedimiento, llamando al metodo base 13.// 14.if (keyData != Keys.Enter) 15.return base.ProcessCmdKey(ref msg, keyData); 16.// 17.// Obtenemos la fila actual 18.// 19.DataGridViewRow row = dataGridView1.CurrentRow; 20. 21.if (rbMostrarMensaje.Checked) 22.{ 23.MessageBox.Show(string.Format("Se ha seleccionado, Cuenta:'{0}' Descripcion:'{1}'", 24.row.Cells["cuenta"].Value, 25.row.Cells["descripcion"].Value)); 26.} 27.else if (rbMostrarForm.Checked) 28.{ 29.int cuenta = Convert.ToInt32(row.Cells["cuenta"].Value); 30.string desc = Convert.ToString(row.Cells["descripcion"].Value); 31. 32.frmSeleccion frm = new frmSeleccion(cuenta, desc); 33.frm.ShowDialog(); 34.} 35. 36.return true; 37.} - El primer punto es detectar si al presionar la tecla el foco lo tiene el control que se quiere trabajar, en este caso el DataGridView - El segundo paso es determinar si la tecla presionada por el usuario es la que se desea controlar, en este caso ser el ENTER Si las dos validaciones anteriores pasaron, se puede recuperar la fila seleccionada en la grilla, y trabajar con la informacin que esta proporcione.
ListView Seleccin de la fila La nica diferencia entre este cdigo y el usado en el DataGridview, ser la forma en que se obtiene el tem seleccionado. Las validaciones en cuanto a la tecla presionada, y el foco en el control activo son idnticas para ambos casos. [C#] 01.protected override bool ProcessCmdKey(ref System.Windows.Forms.Message msg, System.Windows.Forms.Keys keyData) 02.{ 03.// 04.// Si el control DataGridView no tiene el foco, 05.// se abandonamos el procedimiento, llamando al metodo base 06.// 07.if ((!listView1.Focused)) 08.return base.ProcessCmdKey(ref msg, keyData); 09. 10.// 11.// Si la tecla presionada es distinta al ENTER, 12.// se abandonamos el procedimiento, llamando al metodo base 13.// 14.if (keyData != Keys.Enter) 15.return base.ProcessCmdKey(ref msg, keyData); 16. 17.// 18.// Sino hay item seleccinado en la lista 19.// se abandonamos el procedimiento, llamando al metodo base 20.// 21.if(listView1.SelectedItems.Count == 0) 22.return base.ProcessCmdKey(ref msg, keyData); 23. 24.// 25.// Obtenemos la fila actual 26.// 27.ListViewItem item = listView1.SelectedItems[0]; 28. 29.if (rbMostrarMensaje.Checked) 30.{ 31.MessageBox.Show(string.Format("Se ha seleccionado, Cuenta:'{0}' Descripcion:'{1}'", 32.item.Text, 33.item.SubItems[1].Text)); 34.} 35.else if (rbMostrarForm.Checked) 36.{ 37.int cuenta = Convert.ToInt32(item.Text); 38.string desc = Convert.ToString(item.SubItems[1].Text); 39. 40.frmSeleccion frm = new frmSeleccion(cuenta, desc); 41.frm.ShowDialog(); 42.} 43. 44.return true; 45.}
[DataGridView] - ComboBox y evento SelectedIndexChanged
Introduccin
Uno de los problemas al trabajar con el DataGridView y los combos en las celdas, es que no hay un eventos preciso que sea lanzado al cambiar la seleccin por parte del usuario. El evento CellValueChanged se podra decir que es el mas cercano a utilizar, pero este solo se produce cuando la celda se deja de editar, o sea hay que salir de la edicin de la celda, y adems haber cambiado el tem seleccionado para que el evento se produzca. Es por este punto que este articulo explicara como adjuntar el combo definido en una columna de tipo DataGridViewComboBoxColumn, al evento SelectedIndexChanged, el cual de forma estndar no esta disponible en la grilla.
Planteo del problema
Se dispone de una grilla, la cual presenta un combo en una de sus columnas, y un check que habilita la seleccin de la lista de productos. El usuario al cambiar la seleccin del combo, de forma automtica el sistema debera marcarse el checkbox en la misma fila en edicin.
Primer planteo de solucin
Para resolver el problema sern necesarios dos eventos: - EditingControlShowing, el cual se lanza cuando la celda entre en estado de edicin - SelectedIndexChanged, el cual ser asignado al control combo de la celda que se este editando
01.private void dataGridView1_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e) 02.{ 03.DataGridViewComboBoxEditingControl dgvCombo = e.Control asDataGridViewComboBoxEditingControl; 04. 05.if (dgvCombo != null) 06.{ 07.// 08.// se remueve el handler previo que pudiera tener asociado, a causa ediciones previas de la celda 09.// evitando asi que se ejecuten varias veces el evento 10.// 11.dgvCombo.SelectedIndexChanged -= new EventHandler(dvgCombo_SelectedIndexChanged); 12. 13.dgvCombo.SelectedIndexChanged += newEventHandler(dvgCombo_SelectedIndexChanged); 14.} 15. 16.} 17. 18.private void dvgCombo_SelectedIndexChanged(object sender, EventArgs e) 19.{ 20.// 21.// se recupera el valor del combo 22.// a modo de ejemplo se escribe en consola el valor seleccionado 23.// 24.ComboBox combo = sender as ComboBox; 25. 26.Console.WriteLine(combo.SelectedValue); 27. 28.// 29.// se accede a la fila actual, para trabajr con otor de sus campos 30.// en este caso se marca el check si se cambia la seleccion 31.// 32.DataGridViewRow row = dataGridView1.CurrentRow; 33. 34.DataGridViewCheckBoxCell cell = row.Cells["Seleccionado"] asDataGridViewCheckBoxCell; 35.cell.Value = true; 36.}
Aqu hay algunos puntos a detallar: - Como se observa en el evento EditingControlShowing, este tiene un argumento en el evento que permite tomar que control esta siendo editado, puntualmente el e.Control, el cual puede ser convertido a un tipo especifico se quiere trabajar, en este caso el combobox, cualquier otra celda no ser del mismo tipo por lo tanto la conversin devolver null. Vale aclarar que en este caso usar esta lnea: DataGridViewComboBoxEditingControl dgvCombo = e.Control as DataGridViewComboBoxEditingControl; o esta otra: ComboBox dgvCombo = e.Control as ComboBox; es indiferente, con ambas funciona correctamente. - Seguramente se preguntaran porque se esta realizando la desasignacin del evento, cuando en la lnea siguiente se vuelve adjunta. Esto bsicamente se realiza porque si en varias oportunidades es editada la misma celda, en cada ingreso al evento se asignara un nuevo handler, o sea no es pisado el previo o existente, provocando que se lance mas de una vez el mismo evento, lo cual no es el efecto deseado. - En este ejemplo no se hizo, pero podra haberse preguntado si el control en edicin es del tipo ComboBox, mediante el agregado de if, y el uso del is, para luego en caso de ser afirmativo en ese caso si convertir al tipo necesario. 01.private void dataGridView1_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e) 02.{ 03.if (e.Control is ComboBox) 04.{ 05.DataGridViewComboBoxEditingControl dgvCombo = e.Control asDataGridViewComboBoxEditingControl; 06. 07.// 08.// se remueve el handler previo que pudiera tener asociado, a causa ediciones previas de la celda 09.// evitando asi que se ejecuten varias veces el evento 10.// 11.dgvCombo.SelectedIndexChanged -= new EventHandler(dvgCombo_SelectedIndexChanged); 12. 13.dgvCombo.SelectedIndexChanged += newEventHandler(dvgCombo_SelectedIndexChanged); 14.} 15. 16.}
Problema detectado en la primer solucin
Si bien el ejemplo anterior funciona correctamente a primera vista, hay un efecto que se puede llegar a manifestarse, el cual no es nada deseable. Resulta que en ciertas ocasiones luego de haber editado una de las celdas del combo y seleccionado un tem, esta funciono correctamente y marco el check de la fila. Pero al editar otra celda en una fila distinta, sin haber cambiado opcin alguna, se dispara el evento del combo, marcando el check, cuando no debera hacerlo en ese momento, ya que no hubo cambio de seleccin alguna. Esto se debe a que el combo queda con el evento asignado, y lo lanza cuando entra en edicin.
Segundo Planteo de solucin
Este escenario, si bien resuelve el efecto en la seleccin descripto en los pasos previo, tiene un punto no tan bonito en el cdigo, ya que debe conservar el control que se esta editando de forma global al formulario. Bsicamente la resolucin del problema es realizada mediante la quita del evento del combo cuando se deja de editar la celda, para lo cual se agrega el evento CellEndEdit.
01.DataGridViewComboBoxEditingControl dgvCombo; 02. 03.private void dataGridView1_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e) 04.{ 05.dgvCombo = e.Control as DataGridViewComboBoxEditingControl; 06. 07.if (dgvCombo != null) 08.{ 09.dgvCombo.SelectedIndexChanged += newEventHandler(dvgCombo_SelectedIndexChanged); 10.} 11. 12.} 13. 14.private void dvgCombo_SelectedIndexChanged(object sender, EventArgs e) 15.{ 16.// 17.// se recupera el valor del combo 18.// a modo de ejemplo se escribe en consola el valor seleccionado 19.// 20.ComboBox combo = sender as ComboBox; 21. 22.Console.WriteLine(combo.SelectedValue); 23. 24.// 25.// se accede a la fila actual, para trabajr con otor de sus campos 26.// en este caso se marca el check si se cambia la seleccion 27.// 28.DataGridViewRow row = dataGridView1.CurrentRow; 29. 30.DataGridViewCheckBoxCell cell = row.Cells["Seleccionado"] asDataGridViewCheckBoxCell; 31.cell.Value = true; 32.} 33. 34.private void dataGridView1_CellEndEdit(object sender, DataGridViewCellEventArgs e) 35.{ 36. 37.if (dgvCombo != null) 38.dgvCombo.SelectedIndexChanged -= newEventHandler(dvgCombo_SelectedIndexChanged); 39. 40.}
Puntos a remarcar: - Se debe conservar el control combobox editado de forma global del formulario, de esta forma al terminar la edicin, poder remover el evento. Este problema se presenta ya que no existe algn otro evento en la grilla, en donde su argumento devuelva el control que lo genera, de la misma forma en que lo hace el evento EditingControlShowing, con su argumento e.Control - En el evento EditingControlShowing solo hace falta agregar el handler al evento, ya que la remocin se realiza en esta oportunidad cuando es terminada la edicin en el eventoCellEndEdit
[DataGridView] Clculos Totales en las filas y columnas
Introduccin
Muchas de las veces que se opera con el control DataGridView es necesario realizar clculos sobre el mismo, por lo general estos requieres del input del usuario de ciertos valores que trabajaran sobre otros ya cargados en el control En este articulo tratare de de mostrar como hacer uso del control DataGridView para poder realizar estos clculos, reflejando el resultado como totales de filas y columnas.
Carga de los datos en la grilla
Esta ser la primer operacin ha realizar, la carga de los datos de los productos en la grilla. 01.private void frmPedidos_Load(object sender, EventArgs e) 02.{ 03.// 04.// Se recupera los datos de los productos desde la tabla 05.// 06.dtoProductos datos = ProductoDAL.ProductosGetAll(); 07. 08.// 09.// Se agrega un registro adicional al DataTable, para representar la fila de totales 10.// 11.dtoProductos.ProductosRow rowTotal = datos.Productos.NewProductosRow(); 12.datos.Productos.Rows.Add(rowTotal); 13. 14.// 15.// Se bindean los datos a la grilla 16.// 17.dataGridView1.AutoGenerateColumns = false; 18.dataGridView1.DataSource = datos; 19.dataGridView1.DataMember = "Productos"; 20. 21.// 22.// Se selecciona la ultima fila de Totales y se marca como readonly 23.// para evitar la seleccion por el usuario 24.// 25.DataGridViewRow row = dataGridView1.Rows[dataGridView1.Rows.Count - 1]; 26.row.ReadOnly = true; 27. 28.// 29.// Se asigna el evento para detectar los cambios que el usuario realice 30.// 31.dataGridView1.CellValueChanged +=newDataGridViewCellEventHandler(dataGridView1_CellValueChanged); 32.}
Como se puede apreciar se realizan algunas operaciones programticamente sobre los datos antes de bindearlos, por ejemplo una de las principales es al agregado de una fila adicional al final del datatable ,esta operacin es importante ya que permitir visualizar la fila de totales al final de la grilla. Otra operacin importante es realizada luego de bindear, en donde se pone en readonly la ltima fila para evitar que el usuario la edite. Algo a remarcar es la asignacin del evento manuablemente en la ltima lnea del evento Load del formulario, esta asignacin es realizada en este punto ya que si se realiza por medio del cuadro de propiedades del Visual Studio, el evento CellValueChanged ser lanzado varias veces cuando se carga la grilla, lo cual se evita al no asignar el el evento al comienzo, este evento solo es necesario ante la edicin del usuario y no en la carga del mismo.
Calculo de totales
Ante la edicin del campo de pedido o la seleccin de uno de los check de la columna de seleccin, es que se disparara este evento.
01.private void dataGridView1_CellValueChanged(object sender, DataGridViewCellEventArgs e) 02.{ 03.// 04.// Solo se trabaja ante los cambios en la columan de los checkbox 05.// y el ingreso de una canifad por el usuario 06.// 07.if (dataGridView1.Columns[e.ColumnIndex].Name == "Seleccion" || 08.dataGridView1.Columns[e.ColumnIndex].Name == "Pedido") 09.{ 10.decimal totalColumna = 0; 11. 12.// 13.// Se recorre fila a fila para recalcular el total despues del cambio 14.// 15.foreach (DataGridViewRow row in dataGridView1.Rows) 16.{ 17.// 18.// Se selecciona la celda del checkbox 19.// 20.DataGridViewCheckBoxCell cellSelecion = row.Cells["Seleccion"] asDataGridViewCheckBoxCell; 21. 22.// 23.// Se valida si esta checkeada 24.// 25.if (Convert.ToBoolean(cellSelecion.Value)) 26.{ 27.// 28.// Se valida si el usuario ingreso un valor en la celda de pedido 29.// 30.decimal pedido = 0; 31.if (!decimal.TryParse(Convert.ToString(row.Cells["Pedido"].Value),out pedido)) 32.continue; 33. 34.// 35.// Se realiza el calculo para la fila, asignado el total en la celda "Total" 36.// de la misma 37.// 38.decimal totalFila = Convert.ToDecimal(row.Cells["PrecioUnitario"].Value) * pedido; 39.row.Cells["Total"].Value = totalFila; 40. 41.// 42.// Se aumula el total de cada una de las filas 43.// 44.totalColumna += totalFila; 45.} 46.} 47. 48.// 49.// Se toma la ultima fila del total general, asignando el valor acumulado en el calculo 50.// 51.DataGridViewRow rowTotal = dataGridView1.Rows[dataGridView1.Rows.Count - 1]; 52.rowTotal.Cells["Total"].Value = totalColumna; 53. 54.} 55.} En este evento se recorrer cada una de las filas de la grilla realizando los clculos a nivel de la propia fila, pero tambin de la columna de totales. Adicionalmente se agrego el evento de validacin, ante una entrada incorrecta del usuario en la celda de pedidos, si el usuario ingresa letras se mostrara un alerta en la fila. 01.private void dataGridView1_CellValidating(object sender, DataGridViewCellValidatingEventArgs e) 02.{ 03.if (dataGridView1.Columns[e.ColumnIndex].Name == "Pedido") 04.{ 05.// 06.// Si el campo esta vacio no lo marco como error 07.// 08.if (string.IsNullOrEmpty(e.FormattedValue.ToString())) 09.return; 10. 11.// 12.// Solo se valida ante el ingreso de un valor en el campo 13.// 14.decimal pedido = 0; 15.if (!decimal.TryParse(e.FormattedValue.ToString(), out pedido)) 16.{ 17.DataGridViewRow row = dataGridView1.Rows[e.RowIndex]; 18.row.ErrorText = "Debe ingresar un numero valido"; 19.e.Cancel = true; 20.} 21.} 22.} 23. 24.// 25.// Este evento es usado al presiona ESC cancelando la edicion 26.// se elimine el mensaje de error en la fila 27.// 28.private void dataGridView1_CellEndEdit(object sender, DataGridViewCellEventArgs e) 29.{ 30.dataGridView1.Rows[e.RowIndex].ErrorText = String.Empty; 31.}
Nota: Hay un problema en las validaciones en la grilla. Si por alguna razn cuando usa las validaciones en el DataGridView, no visualiza el icono con el mensaje del error esto se puede deber a que la propiedad AutoSizeRowsMode no esta asignada con el valor None. DataGridView1.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.None tenga en cuanta este punto cuando use las validaciones
[DataGridView] - Uso del DataGridViewComboBoxColumn
Introduccin
Este articulo tendr por objetivo mostrar como trabajar con las columna del tipo ComboBox que se encuentran dentro de una celda del datagridview.
1- Definicin de las columnas en tiempo de diseo
Un paso importante es la definicin de las columnas para ello en este caso explicare como hacerlo en tiempo de diseo y poder as controlar que datos visualizar. La opcin para realizar esta operacin se encuentra haciendo click con el botn derecho del mouse en el control DataGridView del formulario, visualizando una lista de tems como se muestran en la imagen
Aqu puede seleccionarse dos opciones: - Agregar nuevas columnas a la grilla por medio de la opcin Add Column visualizndose el siguiente cuadro:
Como se observa en la imagen, puede definirse informacin rpida del tipo de columna que se quiere representar en la grilla. - Editar columnas existentes, mediante la opcin Edit Columns visualizando un cuadro como el siguiente
Lo interesante de esto es que uno podr controlar que visualizar, en que orden, formato, tipo de columna y adems todo desde un entorno visual La idea de estos dilogos es definir rpidamente las columnas mediante la opcin de Add Column para luego pasar a la edicin mediante Edit Columns y especificar propiedades que son importantes para que todo funcione. Una de las propiedades importantes es DataPropertyName, esta es fundamental para indicar que campo del origen de datos ser asignado a esa columna. Al momento de cargar la grilla el valor de esa propiedad ser tomado del origen de datos y asea un DataTable, o List<>, o cualquier otro que sea asignado y se mapear con la columna usando esta propiedad. Sino se asigna informacin a la propiedad DataPropertyName ese campo no cargara datos alguno, lo cual puede ser interesante para campos calculados como veremos en ejemplo mas adelante. Es importante adems que la propiedad AutoGenerateColumns sea establecida en false cuando se definan las columnas en tiempo de diseo, ya que en caso de no hacerlo se aadir a la grilla las columnas generadas en runtime, lo cual no es deseable en este caso.
2 Asignacin de los datos a la columna DataGridViewComboBoxColumn
Empezaremos por cargar la informacin en un ejemplo simple, en este solo se tendr un nico campo del tipo combobox en el columna del DataGridView. En este caso se trata de una grilla de producto con sus precios unitarios, adems cada producto pertenece a una marca especifica, que podr seleccionarse entre las disponibles por el sistema. Los pasos a seguir sern: - se recuperara la columna que fue definida del tipo combobox a la cual se le asignaran los datos a desplegar, en este caso sern las Marcas disponibles. - y por ultimo se cargara la grilla con los datos de los Productos. El formulario que visualizara ser el siguiente:
La carga de los datos se ha realizado en el evento Load del formulario 01.private void Form1_Load(object sender, EventArgs e) 02.{ 03.// 04.// Asigno los datos del combo de marcas 05.// 06.DataGridViewComboBoxColumn comboboxColumn = dataGridView1.Columns["Marca"] asDataGridViewComboBoxColumn; 07. 08.comboboxColumn.DataSource = ProductosDAL.GetAllMarca(); 09.comboboxColumn.DisplayMember = "Descripcion"; 10.comboboxColumn.ValueMember = "IdMarca"; 11. 12.// 13.// bindeo los datos de los productos a la grilla 14.// 15.dataGridView1.AutoGenerateColumns = false; 16.dataGridView1.DataSource = ProductosDAL.GetAllProductos(); 17. 18.} Es interesante notar que la primer parte se recupera la columna del DataGridView que define el combobox, la cual se programa como si se tratara de un combobox normal de .net, utilizando las propiedades DataSource, a la cual se le asignado el origen de datos con la lista de Marcas, el DisplayMember y ValueMember, para asignar que campo de la lista de Marcas ser visible al usuario y cual ser el id de cada tem listado. El segunda parte carga los datos del DataGridView, tomando todos los producto a mostrar en la grilla. Adems se especifica la propiedad AutoGenerateColumns definiendo que solo las columnas creadas en tiempo de diseo sern las visibles. A continuacin se visualizara los mtodos utilizados para cargar los datos en el DataGridView 01.public static List<MarcaEntity> GetAllMarca() 02.{ 03.string sql = @"SELECT IdMarca 04.,Descripcion 05.FROM Marcas"; 06. 07.List<MarcaEntity> list = new List<MarcaEntity>(); 08. 09.using (OleDbConnection conn = newOleDbConnection(ConfigurationManager.ConnectionStrings["default"].ToString())) 10.{ 11. 12.OleDbCommand command = new OleDbCommand(sql, conn); 13. 14.conn.Open(); 15. 16.OleDbDataReader reader = command.ExecuteReader(); 17. 18.while (reader.Read()) 19.{ 20.list.Add(LoadMarca(reader)); 21.} 22. 23.return list; 24.} 25.} 26. 27.private static MarcaEntity LoadMarca(IDataReader reader) 28.{ 29.MarcaEntity marca = new MarcaEntity(); 30. 31.marca.IdMarca = Convert.ToInt32(reader["IdMarca"]); 32.marca.Descripcion = Convert.ToString(reader["Descripcion"]); 33. 34.return marca; 35.}
3 Realizar una operacin al cambiar la seleccin del combo
En este seccin se analizara como poder trabajar con un combobox que ha sido agregado a la grilla. En este ejemplo se agrego un atributo nuevo al producto, referido a un descuento, segn el el valor seleccionado del combo se realizara una operacin con el mismo y el valor calculado ser presentado en otra celda de la misma fila en donde se visualiza la informacin del producto. El formulario ahora tomara la siguiente forma
Adems si se analiza las propiedades de la nueva columna se podr apreciar que la propiedad DataPropertyName se le ha especificado el nombre del campo de la tabla de productos, y es el mismo nombre de la propiedad en la clase ProductoEntity.
A diferencia el ejemplo anterior en este solo se agregaron las lnea para cargar los tems de descuento 01.private void Form1_Load(object sender, EventArgs e) 02.{ 03.// 04.// Asigno los datos del combo de marcas 05.// 06.DataGridViewComboBoxColumn comboboxColumn = dataGridView1.Columns["Marca"] asDataGridViewComboBoxColumn; 07. 08.comboboxColumn.DataSource = ProductosDAL.GetAllMarca(); 09.comboboxColumn.DisplayMember = "Descripcion"; 10.comboboxColumn.ValueMember = "IdMarca"; 11. 12.// 13.// Asigno los datos del combo de descuentos 14.// 15.DataGridViewComboBoxColumn dgccomboDescuento = dataGridView1.Columns["Descuento"] as DataGridViewComboBoxColumn; 16. 17.dgccomboDescuento.DataSource = ProductosDAL.GetAllDescuentos(); 18.dgccomboDescuento.DisplayMember = "Descripcion"; 19.dgccomboDescuento.ValueMember = "IdDescuento"; 20. 21.// 22.// bindeo los datos de los productos a la grilla 23.// 24.dataGridView1.AutoGenerateColumns = false; 25.dataGridView1.DataSource = ProductosDAL.GetAllProductos(); 26. 27.} Pero lo mas importante es ver como se trabaja con el combo, detectando un cambio en el tem y realizando el calculo del descuento. 01.private void dataGridView1_CellValueChanged(object sender, DataGridViewCellEventArgs e) 02.{ 03. 04.if (dataGridView1.Columns[e.ColumnIndex].Name == "Descuento") 05.{ 06.// 07.// se obtiene el valor seleccionado en el combo 08.// 09.DataGridViewComboBoxCell combo = dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex] asDataGridViewComboBoxCell; 10. 11.int idDescuento = Convert.ToInt32(combo.Value); 12. 13.// 14.// se recupera por el id la info del descuento 15.// 16.DescuentoEntity descuento = ProductosDAL.GetDescuentosById(idDescuento); 17. 18.// 19.// se calcula el descuento 20.// 21.DataGridViewCell cellPrecioUnitario = dataGridView1.Rows[e.RowIndex].Cells["Precio"]; 22.DataGridViewCell cellPrecioFinal = dataGridView1.Rows[e.RowIndex].Cells["PrecioFinal"]; 23. 24.decimal valordescontar = (descuento.Porcentaje * Convert.ToDecimal(cellPrecioUnitario.Value)) / 100; 25. 26.cellPrecioFinal.Value = Convert.ToDecimal(cellPrecioUnitario.Value) - valordescontar; 27.} 28.} En este caso se hizo uso del evento CellValueChange, y dentro de este se realizando las operaciones para trabajar con el valor seleccionado del combo. - Primeramente se valida que siempre se trabaje con la columna que uno quiere operar, en este caso por el nombre se valida que sea la definida para el descuento. Debe recordarse que estos eventos tambin puede disparase para la edicin de otras celdas para las dems columnas. Pero en este caso como el calculo solo interesa hacerlo en la columna de descuento es esta la verificada. - Como segundo pasos se toma el id del descuento seleccionado en el combo, debe recordarse que al momento de cargar los tems del combo, fueron los id los que se unieron a la propiedad ValueMember. - Con el id del descuento se accede a la base de datos para recuperar la entidad del descuento y con esta el valor del porcentaje que ser usado en el calculo - Por ultimo se recuperas la informacin de las celdas que restan y se procede a realizar el calculo del porcentaje que ser desplegado en la ultima columna de la grilla. Algo interesante a notar es que esta ultima columna que se hace llamar Precio Final no tiene valor alguno en la propiedad DataPropertyName, es por ello que no se carga ningn valor proveniente de la base de datos.
[DataGridView] Parte 3 Pasaje de informacin entre grillas en distintos formulario
Introduccin Este artculo es consecuencia de otros descriptos con anterioridad C# Comunicar formularios de forma desacoplada Como se habr visto comunicar formularios de forma desacoplada puede no se tan simple alguna veces y es justamente cuando se hace uso de informacin entre grillas que la situacin puede ser algo mas compleja Este ejemplo intenta demostrar como realizar la comunicacin y desde un formulario hijo pasar informacin de tems seleccionados al un formulario padre o quien realiza la llamada. Definicin de la Interfaz Para la comunicacin eficiente de los formulario, se crearan un contrato que permitir enlazarlos con el mnimo acoplamiento entre ellos. 1.interface IAddItem 2.{ 3.void AddNewItem(DataGridViewRow row); 4.} Como se observa el mtodo que tomara el retorno de la seleccin del tem define un DataGridViewRow, o sea un registro completo seleccionado en la grilla del formulario hijo. Formulario Padre Como se observara el formulario padre que realizara la apertura debe implementar la interfaz IAddItem definida en el punto anterior.
Es importante destacar algunas lneas: - Lnea 11: es el punto en donde se realiza la apertura del forma hijo, y es all donde se le indica quien es el padre o quien esta realizando al apertura del formulario, esto se esta indicando al hacer uso del this en el parmetro del mtodo Show() - Lneas 17-24: en estas lnea de cdigo se estar tomando la fila que se retorna de la seleccin, se recupera cada valor y se arma el nuevo registro, en este punto en caso de que fuera necesario se podra realizar clculos o modificar los datos, para ser luego insertados en la grilla de tems seleccionados. Formulario Hijo Este formulario contiene la grilla con los tems que pueden ser seleccionados, los cuales a modo de ejemplo fueron creados manualmente en un DataTable. El punto clave aqu es el botn que enva el registro seleccionado, del datagridview del formulario hijo al formulario padre que realizo la llamada: 01.private void button1_Click(object sender, EventArgs e) 02.{ 03.DataGridViewRow row = this.dataGridView1.SelectedRows[0] as DataGridViewRow; 04. 05. 06.IAddItem parent = this.Owner as IAddItem; 07.parent.AddNewItem(row); 08. 09.this.Close(); 10.} Como se observa se toma la fila seleccionada, y acto seguido se llamada al mtodo de la interfaz del formulario que realizo la llamada. El parmetro this enviado en el mtodo Show() es justamente la propiedad Owner del formulario hijo, y al implementar la interfaz este puede ser casteado a el tipo IAddItem sin problemas, para luego invocar al mtodo que define.
[DataGridView] Parte 2 Edicin de celda con form PopUp para la seleccin de tem - KeyDown
El objetivo del articulo es demostrar como en la edicin de la celda se puede lanzar un formulario de bsqueda para la seleccin de un tem determinado, y a retorno del mismo completar la informacin de la fila en edicin con la seleccin del formulario. Para esta operacin se hace uso de propiedades, y clases las cuales permitirn desacoplar ambas grilla, tanto la que originalmente mantiene la lista de productos seleccionados, como la que se despliega y permite la eleccin de un tem determinado. En el formulario cuyo objetico ser llevar la lista de tems elegidos por el usuario se dispone de siguiente cdigo. 01.private void dataGridView1_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e) 02.{ 03.DataGridViewTextBoxEditingControl dText = (DataGridViewTextBoxEditingControl)e.Control; 04. 05.dText.KeyDown -= new KeyEventHandler(dText_KeyDown); 06.dText.KeyDown += new KeyEventHandler(dText_KeyDown); 07.} 08. 09.void dText_KeyDown(object sender, KeyEventArgs e) 10.{ 11.int rowIndex = ((System.Windows.Forms.DataGridViewTextBoxEditingControl)(sender)).EditingControlRowIndex; 12. 13.if (e.Alt && e.KeyCode == Keys.D) 14.{ 15.frmSeleccionarProducto form = new frmSeleccionarProducto(); 16. 17.form.ShowDialog(); 18. 19.Producto productoSeleccionado = form.ProductSelected; 20. 21.DataGridViewRow row = dataGridView1.Rows[rowIndex]; 22.row.Cells["IdProducto"].Value = productoSeleccionado.IdProducto; 23.row.Cells["Descripcion"].Value = productoSeleccionado.Descripcion; 24.row.Cells["precio"].Value = productoSeleccionado.Precio; 25. 26.dataGridView1.EndEdit(); 27.} 28.} Como se observa mucha de la funcionalidad tiene que ver con la asignacin de los eventos que permitirn capturar la pulsacin de la teclas definidas para que se visualice el formulario de PopUp. En este caso si bien es posible utilizar cualquier tecla, se decidi que la combinacin de Alt + D seria la adecuada, pero podra seleccionar la que sea necesario. Como se observa si se detecta la pulsacin de la tecla, se crea una instancia del formulario y se muestra en formulario modal. Al cierre del mismo se captura la propiedad con el tem elegido y se carga en la grilla. El formulario que se desplegara tiene un cdigo muy simple en donde simplemente al hacer dobleclick en una de sus filas, la marcara como seleccionada y cerrar el formulario. 01.private void dataGridView1_CellDoubleClick(object sender, DataGridViewCellEventArgs e) 02.{ 03.DataGridViewRow row = dataGridView1.SelectedRows[0]; 04. 05.this.ProductSelected = new Producto() 06.{ 07.IdProducto = Convert.ToInt32(row.Cells["IdProducto"].Value), 08.Descripcion = Convert.ToString(row.Cells["Descripcion"].Value), 09.Precio = Convert.ToDecimal(row.Cells["precio"].Value), 10.}; 11. 12.this.Close(); 13.}
[DataGridView] Parte 1 Valor de celda Condicional usando CellFormatting
El ejemplo intenta demostrar como una vez que se bindean los datos estos pueden ser acomodados en las celda segn cierta condicin. En este ejemplo se toma un origen de datos con tres columnas pero solo dos sern representadas como datos en la grilla, ya que una condicin indicara si debe
01.private void dataGridView1_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e) 02.{ 03.DataGridViewColumn currentColumn = dataGridView1.Columns[e.ColumnIndex]; 04. 05.if (currentColumn.Name == "Fracciona") 06.{ 07.DataGridViewRow currentRow = dataGridView1.Rows[e.RowIndex]; 08.DataRowView data = currentRow.DataBoundItem as DataRowView; 09. 10.if (data == null) 11.return; 12. 13.if(Convert.ToBoolean(data["fracc"])) 14.currentRow.Cells["tipoventa"].Value = Convert.ToString(data["FORM_VENT"]); 15.else 16.currentRow.Cells["tipoventa"].Value = Convert.ToString(data["PRESENTACI"]); 17. 18.} 19.} En este caso la lgica principal se encuentra en el evento CellFormatting, pues este ser el encargado de realiza la lgica necesaria para decidir que campo de los datos bindeados deben representarse en la celda. Se podr visualizar que un campo que si se ha enlazado a la grilla mediante la propiedadDataPropertyName pero el segunda columnas de la grilla no se le ha asignado este valor ya que ser por medio de cdigo quien decida que valor mostrar. Una de las lneas mas importantes es la 7, ya que esta permite recuperar los datos originales que se estn bindeando a esa fila en particular, y por lo tanto trabajar con ellos. Los datos utilizados para el ejemplo son los siguiente 01.private DataTable GetDataTable() 02.{ 03.DataTable dt = new DataTable(); 04. 05.dt.Columns.Add("fracc", typeof(bool)); 06.dt.Columns.Add("PRESENTACI"); 07.dt.Columns.Add("FORM_VENT"); 08. 09. 10.DataRow row = dt.NewRow(); 11.row["fracc"] = true; 12.row["PRESENTACI"] = "PRESENTACI 1"; 13.row["FORM_VENT"] = "FORM_VENT 1"; 14.dt.Rows.Add(row); 15. 16.row = dt.NewRow(); 17.row["fracc"] = false; 18.row["PRESENTACI"] = "PRESENTACI 2"; 19.row["FORM_VENT"] = "FORM_VENT 2"; 20.dt.Rows.Add(row); 21. 22.row = dt.NewRow(); 23.row["fracc"] = false; 24.row["PRESENTACI"] = "PRESENTACI 3"; 25.row["FORM_VENT"] = "FORM_VENT 3"; 26.dt.Rows.Add(row); 27. 28.row = dt.NewRow(); 29.row["fracc"] = true; 30.row["PRESENTACI"] = "PRESENTACI 4"; 31.row["FORM_VENT"] = "FORM_VENT 4"; 32.dt.Rows.Add(row); 33. 34.return dt; 35. 36.} esto es importante para poder conocer como se accede a la informacin bideada en la grilla. Como funcionalidad adicional se permite que el usuario al marcar o desmarcar una celda esta cambie el contenido con respecto al valor que se obtuvo al momento de bindear la fila 01.private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e) 02.{ 03. 04.DataGridViewColumn currentColumn = dataGridView1.Columns[e.ColumnIndex]; 05. 06.if (currentColumn.Name == "Fracciona") 07.{ 08.DataGridViewCheckBoxCell currentCell = dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex] asDataGridViewCheckBoxCell; 09. 10.DataGridViewRow currentRow = dataGridView1.Rows[e.RowIndex]; 11.DataRowView data = currentRow.DataBoundItem as DataRowView; 12. 13.if (data == null) 14.return; 15. 16.if (Convert.ToBoolean(currentCell.Value)) 17.currentRow.Cells["tipoventa"].Value = Convert.ToString(data["FORM_VENT"]); 18.else 19.currentRow.Cells["tipoventa"].Value = Convert.ToString(data["PRESENTACI"]); 20. 21.dataGridView1.EndEdit(); 22.} 23.} [DataGridView] KeyPress detectar ENTER y bsqueda
El objetivo del artculo es demostrar como mediante la edicin de una celda se puede detectar la presin de la tecla ENTER, la cual ser capturada para realizar una bsqueda con la informacin ingresada en la celda Se debe aclarar que las columnas que no se requiere bsqueda deber asignarse la propiedad readonly para evitar problemas, pues por defecto tambin entraran en la lgica que controla la pulsacin del enter, salvo que se agregue validaciones para que no actu sobre estas celdas.
01.private void dataGridView1_CellEnter(object sender, DataGridViewCellEventArgs e) 02.{ 03.dataGridView1.BeginEdit(false); 04.} 05. 06.private void dataGridView1_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e) 07.{ 08.DataGridViewTextBoxEditingControl dText = (DataGridViewTextBoxEditingControl)e.Control; 09.dText.KeyUp -= new KeyEventHandler(text_KeyUp); 10.dText.KeyUp += new KeyEventHandler(text_KeyUp); 11.} 12. 13.void text_KeyUp(object sender, KeyEventArgs e) 14.{ 15.int rowIndex = ((System.Windows.Forms.DataGridViewTextBoxEditingControl)(sender)).EditingControlRowIndex; 16. 17.if (e.KeyCode == Keys.Enter) 18.{ 19.int valueEntered = Convert.ToInt32(dataGridView1.Rows[rowIndex - 1].Cells["cuenta"].Value); 20. 21.dataGridView1.Rows[rowIndex - 1].Cells["descripcion"].Value =this.Search(valueEntered); 22.} 23.} Como se observa hay varios eventos asociados al DataGridView necesarios para poder controlar la pulsacin del enter en las celdas. Al editar la calda esta asocia el evento una clase de nombre DataGridViewTextBoxEditingControl, la cual representa un TextBox control asociado a una DataGridViewTextBoxCell. Se vera adems que se realiza una operacin de bsqueda, en este caso para simplificar el ejemplo se realiza sobre un datatable cargado previamente, para lo cual se ha utilizado LinQ
Lección 14 y 15 (Entrada de Datos Con La Clase Scanner y La Clase JOptionPane, Transformar Datos Numéricos Tipo String a Int y Double Con El Método ParseInt y ParseDouble, Trabajar Con 2 Decimales Printf)