Algunos Trucos de C#

download Algunos Trucos de C#

of 51

description

Algunos Trucos de C#, Algunos Trucos de C#

Transcript of Algunos Trucos de C#

Como puedo vaciar el contenido de un datagridview?Hace unos dias que lo estoy probando pero no hay manera. Resulta que tengo tengo un datagridview, donde le asigno como datasource un dataset con datos, y luego le asigno el datamember, y me muestra los datos. Hasta aqu ningun problema. El problema viene cuando quiero vaciar este datagridview porque simplemente no quiero mostrar ninguna informacin en l, vamos, que lo quiero vaciar. He probado asignandole el datasource a null, pero visualmente el datagridview sigue con datos. Tambien he probado con la funcion Clear() pero tampoco. Que hago mal?Otra forma de vaciarlo, al menos en c# es:

DataGridView1.Rows.Clear();COLOREAR CELDAS DE UN DATAGRIDVIEWSupongamos que tenemos un control de tipoDataGridViewque tiene tres columnas visibles.Con el siguiente mtodo vamos a poder pintar de un color determinado el fondo de una fila determinada.Los argumentos que recibe el mtodo son: DataGridView visor: El visor del que deseamos pintar el fondo de una de sus lneas Int32 fila: El nmero de la fila que deseamos pintar el fondo Color c: El color del que vamos a pintar el fondo de la filaVemos el cdigo del mtodo:private void gestionaResaltados(DataGridView visor, Int32 fila, System.Drawing.Color c){visor.Rows[fila].Cells[0].Style.BackColor = c;visor.Rows[fila].Cells[1].Style.BackColor = c;visor.Rows[fila].Cells[2].Style.BackColor = c;}

DataGridView: posicionar scrollEsta es una cuestin muy simple y sencilla pero me ha parecido correcto incluirla en un post porque es de ese tipo de cosas que siempre se preguntan y nadie escribe sobre ello porque parece demasiado trivial.Supongamos el caso de un DataGridView que contiene multitud de lneas y el usuario se desplaza por el mismo con un scroll vertical. En un momento dado el usuario cambia el contenido de una celda y actualiza para que los cambios sean volcados en la base de datos que alimenta el DataGridView.Qu ocurre?. Que al actualizar el scroll sube a la parte de arriba, perdiendo de vista en la pantalla el cambio efectuado.La solucin es la siguiente:intindiceFilaSelec=dataGridView1.CurrentRow.Index;dataGridView1.FirstDisplayedScrollingRowIndex=indiceFilaSelec;Tambin se puede obtener el ndice de la fila seleccionada condataGridView1.SelectedRows[0].Index;

Colocar un Ancho Fijo a una Columna de un datagridview en visual C# 2008Puede ser as : private void FormartoGrilla() { dgvPersona.Columns[0].Width = 70; dgvPersona.Columns[1].Width = 150; }

Luego :private void frmCliente_Load(object sender, EventArgs e) { dgvPersona.DataSource = Persona.CargarGrilla(); FormartoGrilla(); }

Pedro vila"El hombre sabio querr estar siempre con quien sea mejor que l."Lima - Per

martes, 1 de junio de 2010[DataGridView] Texto Celdas en MaysculaIntroduccinEn 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 EditingControlShowingEn 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#]private void dataGridView1_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e){ int columnIndex = dataGridView1.CurrentCell.ColumnIndex;

if (dataGridView1.Columns[columnIndex].Name == "Descripcion") { DataGridViewTextBoxEditingControl dText = (DataGridViewTextBoxEditingControl)e.Control;

dText.KeyPress -= new KeyPressEventHandler(dText_KeyPress); dText.KeyPress += new KeyPressEventHandler(dText_KeyPress); }}

void dText_KeyPress(object sender, KeyPressEventArgs e){ int columnIndex = dataGridView1.CurrentCell.ColumnIndex;

if (dataGridView1.Columns[columnIndex].Name == "Descripcion") { e.KeyChar = char.ToUpper(e.KeyChar); }}[VB.NET]Private Sub dataGridView1_EditingControlShowing(ByVal sender As Object, ByVal e As DataGridViewEditingControlShowingEventArgs)

Dim columnIndex As Integer = dataGridView1.CurrentCell.ColumnIndex

If dataGridView1.Columns(columnIndex).Name = "Descripcion" Then

Dim dText As DataGridViewTextBoxEditingControl = DirectCast(e.Control, DataGridViewTextBoxEditingControl)

RemoveHandler dText.KeyPress, AddressOf dText_KeyPress AddHandler dText.KeyPress, AddressOf dText_KeyPress

End If

End Sub

Private Sub dText_KeyPress(ByVal sender As Object, ByVal e As KeyPressEventArgs)

Dim columnIndex As Integer = dataGridView1.CurrentCell.ColumnIndex

If dataGridView1.Columns(columnIndex).Name = "Descripcion" Then

e.KeyChar = Char.ToUpper(e.KeyChar)

End If

End Sub[C#]

[VB.NET]

Resolucin del problema en al asignacin del eventoEl 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#]DataGridViewTextBoxEditingControl dText = null;

private void dataGridView1_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e){ int columnIndex = dataGridView1.CurrentCell.ColumnIndex;

if (dataGridView1.Columns[columnIndex].Name == "Descripcion") { dText = (DataGridViewTextBoxEditingControl)e.Control; dText.KeyPress += new KeyPressEventHandler(dText_KeyPress); }}

private void dataGridView1_CellEndEdit(object sender, DataGridViewCellEventArgs e){ int columnIndex = dataGridView1.CurrentCell.ColumnIndex;

if (dataGridView1.Columns[columnIndex].Name == "Descripcion") { dText.KeyPress -= new KeyPressEventHandler(dText_KeyPress); }}

void dText_KeyPress(object sender, KeyPressEventArgs e){ e.KeyChar = char.ToUpper(e.KeyChar);}[VB.NET]Private dText As DataGridViewTextBoxEditingControl = Nothing

Private Sub dataGridView1_EditingControlShowing(ByVal sender As Object, ByVal e As DataGridViewEditingControlShowingEventArgs) Handles dataGridView1.EditingControlShowing

Dim columnIndex As Integer = dataGridView1.CurrentCell.ColumnIndex

If dataGridView1.Columns(columnIndex).Name = "Descripcion" Then

dText = DirectCast(e.Control, DataGridViewTextBoxEditingControl)

AddHandler dText.KeyPress, AddressOf dText_KeyPress

End IfEnd Sub

Private Sub dataGridView1_CellEndEdit(ByVal sender As Object, ByVal e As DataGridViewCellEventArgs) Handles dataGridView1.CellEndEdit

Dim columnIndex As Integer = dataGridView1.CurrentCell.ColumnIndex

If dataGridView1.Columns(columnIndex).Name = "Descripcion" Then RemoveHandler dText.KeyPress, AddressOf dText_KeyPress End If

End Sub

Private Sub dText_KeyPress(ByVal sender As Object, ByVal e As KeyPressEventArgs)

e.KeyChar = Char.ToUpper(e.KeyChar)

End Sub[C#]

[VB.NET]

Publicado porLeandro Tuttinien10:024 comentarios:Etiquetas:DataGridViewdomingo, 2 de mayo de 2010C# - [DataGridView] DataGridViewComboBoxColumn Variar contenido del combobox respecto a la filaIntroduccinEl objetivo del articulo 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 ComboBoxEn 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.private void frmSucursales_Load(object sender, EventArgs e){ SucursalesEntities sucursalesContext = new SucursalesEntities();

dgvScursales.AutoGenerateColumns=false; dgvScursales.DataSource = sucursalesContext.Sucursales;

// // Luego de bindear la grilla, cargo el contenido de cada fila // en el combo de telefonos para cada sucursal // LoadGrillaComboBoxTelefonos();

}

private void LoadGrillaComboBoxTelefonos(){ foreach (DataGridViewRow row in dgvScursales.Rows) { int idSucursal = Convert.ToInt32(row.Cells["IdSucursal"].Value);

DataGridViewComboBoxCell comboboxCell = row.Cells["Telefonos"] as DataGridViewComboBoxCell; SucursalesEntities sucursalesContext = new SucursalesEntities();

comboboxCell.DataSource = sucursalesContext.Telefonos.Where(x => x.IdSucursal == idSucursal); comboboxCell.ValueMember = "Id"; comboboxCell.DisplayMember = "Numero";

}}Algunos ComentariosDurante 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.ElCellFormatting, 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.ElRowsAdded, 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#]

[VB.NET]

Publicado porLeandro Tuttinien20:4125 comentarios:Etiquetas:DataGridView,WinFormjueves, 22 de abril de 2010C# - [DataGridView] Pasar Registros entre GrillasIntroduccin

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.private void frmPedidos_Load(object sender, EventArgs e){ // // Se recupera los datos de los productos desde la tabla // dtoProductos datos = ProductoDAL.ProductosGetAll();

// // Se bindean los datos a la grilla // dgvProductos.AutoGenerateColumns = false; dgvProductos.DataSource = datos; dgvProductos.DataMember = "Productos";

}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.private void btnSeleccionar_Click(object sender, EventArgs e){ // // Se define una lista temporal de registro seleccionados // List rowSelected = new List();

// // Se recorre ca registro de la grilla de origen // foreach (DataGridViewRow row in dgvProductos.Rows) { // // Se recupera el campo que representa el checkbox, y se valida la seleccion // agregandola a la lista temporal // DataGridViewCheckBoxCell cellSelecion = row.Cells["Seleccion"] as DataGridViewCheckBoxCell;

if (Convert.ToBoolean(cellSelecion.Value)) { rowSelected.Add(row); } }

// // Se agrega el item seleccionado a la grilla de destino // eliminando la fila de la grilla original // foreach (DataGridViewRow row in rowSelected) { dgvSeleccion.Rows.Add(new object[] {false, row.Cells["Descripcion"].Value, row.Cells["PrecioUnitario"].Value, row.Cells["UnidadMedida"].Value});

dgvProductos.Rows.Remove(row); }

}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 listaSeleccin 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 menciono en el paso previo, la lista de origen esta 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.private void btnQuitar_Click(object sender, EventArgs e){ // // Se define una lista temporal de registro seleccionados // List rowSelected = new List();

// // Se recorre cada fila de la grilla de seleccion y se determian que registros estan checkeados // foreach (DataGridViewRow row in dgvSeleccion.Rows) { DataGridViewCheckBoxCell cellSelecion = row.Cells["SeleccionSel"] as DataGridViewCheckBoxCell;

if (Convert.ToBoolean(cellSelecion.Value)) { rowSelected.Add(row); } }

// // Se valida si hay algun registro por eliminar // if (rowSelected.Count > 0) { // // Se recupera el origen de datos que tiene asignada la grilla de productos // dtoProductos datos = dgvProductos.DataSource as dtoProductos;

// // Se recorre cada item seleccionado y se arma programaticamente la fila del DataTable // se elimina el registro de la grilla de selecciones // foreach (DataGridViewRow row in rowSelected) {

dtoProductos.ProductosRow productoRow = datos.Productos.NewProductosRow();

productoRow.Descripcion = Convert.ToString(row.Cells["DescripcionSel"].Value); productoRow.PrecioUnitario = Convert.ToDecimal(row.Cells["PrecioUnitarioSel"].Value); productoRow.UnidadMedida = Convert.ToString(row.Cells["UnidadMedidaSel"].Value); datos.Productos.Rows.Add(productoRow);

dgvSeleccion.Rows.Remove(row); }

// // Se binden los datos nuevamente, pero ahora con los nuevos registros // agregados del paso anterior // dgvProductos.AutoGenerateColumns = false; dgvProductos.DataSource = datos; dgvProductos.DataMember = "Productos"; }}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#]

[VB.NET]

Publicado porLeandro Tuttinien8:36116 comentarios:Etiquetas:DataGridViewjueves, 15 de abril de 2010C# - [DataGridView] Uso del CheckBox - DataGridViewCheckBoxColumnIntroduccinEl articulo intentara mostrar las algunas forma en que se puede utilizar el checkbox en un control DataGridView.Detectar el cambio en la seleccinPara realizar la tarea se har uso de dos eventos que pueden ser igual de tiles, el CellValueChange y el CellContentClickDe 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.private void dataGridView1_CellValueChanged(object sender, DataGridViewCellEventArgs e){//// Solo se trabaja ante los cambios en la columan de los checkbox //if (dataGridView1.Columns[e.ColumnIndex].Name == "Seleccion") {//// Se toma la fila seleccionada//DataGridViewRow row = dataGridView1.Rows[e.RowIndex];

//// Se selecciona la celda del checkbox//DataGridViewCheckBoxCell cellSelecion = row.Cells["Seleccion"] as DataGridViewCheckBoxCell; //// Se valida si esta checkeada//if (Convert.ToBoolean(cellSelecion.Value)) {

string mensaje = string.Format("Evento CellValueChanged.\n\nSe ha seccionado, \nDescripcion: '{0}', \nPrecio Unitario: '{1}', \nMedida: '{2}'", row.Cells["Descripcion"].Value, row.Cells["PrecioUnitario"].Value, row.Cells["UnidadMedida"].Value);

MessageBox.Show(mensaje, "", MessageBoxButtons.OK, MessageBoxIcon.Information);

}

}

}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.private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e){ // // Detecta si se ha seleccionado el header de la grilla // if (e.RowIndex == -1) return;

if (dataGridView1.Columns[e.ColumnIndex].Name == "Seleccion") {

// // Se toma la fila seleccionada // DataGridViewRow row = dataGridView1.Rows[e.RowIndex];

// // Se selecciona la celda del checkbox // DataGridViewCheckBoxCell cellSelecion = row.Cells["Seleccion"] as DataGridViewCheckBoxCell;

if (Convert.ToBoolean(cellSelecion.Value)) {

string mensaje = string.Format("Evento CellContentClick.\n\nSe ha seccionado, \nDescripcion: '{0}', \nPrecio Unitario: '{1}', \nMedida: '{2}'", row.Cells["Descripcion"].Value, row.Cells["PrecioUnitario"].Value, row.Cells["UnidadMedida"].Value);

MessageBox.Show(mensaje, "", MessageBoxButtons.OK, MessageBoxIcon.Information);

} else { string mensaje = string.Format("Evento CellContentClick.\n\nSe ha quitado la seleccion, \nDescripcion: '{0}', \nPrecio Unitario: '{1}', \nMedida: '{2}'", row.Cells["Descripcion"].Value, row.Cells["PrecioUnitario"].Value, row.Cells["UnidadMedida"].Value);

MessageBox.Show(mensaje, "", MessageBoxButtons.OK, MessageBoxIcon.Information);

} }}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 delCommitEditprivate void dataGridView1_CurrentCellDirtyStateChanged(object sender, EventArgs e){ if (dataGridView1.IsCurrentCellDirty) { dataGridView1.CommitEdit(DataGridViewDataErrorContexts.Commit); }}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[C#]

[VB.NET]

Aplicar formato a la seleccinTeniendo en cuenta lo contado en la seccin anterior, aplicar un formato a la fila seleccionada no debera ser un misterio.private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e){ // // Detecta si se ha seleccionado el header de la grilla // if (e.RowIndex == -1) return;

if (dataGridView1.Columns[e.ColumnIndex].Name == "Seleccion") {

// // Se toma la fila seleccionada // DataGridViewRow row = dataGridView1.Rows[e.RowIndex];

// // Se selecciona la celda del checkbox // DataGridViewCheckBoxCell cellSelecion = row.Cells["Seleccion"] as DataGridViewCheckBoxCell;

if (Convert.ToBoolean(cellSelecion.Value)) row.DefaultCellStyle.BackColor = Color.Green; else row.DefaultCellStyle.BackColor = Color.White;

}}

private void dataGridView1_CurrentCellDirtyStateChanged(object sender, EventArgs e){ if (dataGridView1.IsCurrentCellDirty) { dataGridView1.CommitEdit(DataGridViewDataErrorContexts.Commit); }}Simplemente ante la deteccin de la seleccin del usuario se cambia el color de la fila usando el DefaultCellStyle.BackColor.[C#]

[VB.NET]

Publicado porLeandro Tuttinien5:5969 comentarios:Etiquetas:DataGridView,WinFormjueves, 1 de abril de 2010C# - [Winforms] Seleccionar Fila con ENTER DataGridView y ListViewIntroduccinEste 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 mtodoProcessCmdKeydel 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 filaComo haba comentado todo el trabajo esta en la funcin:[C#]protected override bool ProcessCmdKey(ref System.Windows.Forms.Message msg, System.Windows.Forms.Keys keyData){ // // Si el control DataGridView no tiene el foco, // se abandonamos el procedimiento, llamando al metodo base // if ((!dataGridView1.Focused)) return base.ProcessCmdKey(ref msg, keyData);

// // Si la tecla presionada es distinta al ENTER, // se abandonamos el procedimiento, llamando al metodo base // if (keyData != Keys.Enter) return base.ProcessCmdKey(ref msg, keyData); // // Obtenemos la fila actual // DataGridViewRow row = dataGridView1.CurrentRow;

if (rbMostrarMensaje.Checked) { MessageBox.Show(string.Format("Se ha seleccionado, Cuenta:'{0}' Descripcion:'{1}'", row.Cells["cuenta"].Value, row.Cells["descripcion"].Value)); } else if (rbMostrarForm.Checked) { int cuenta = Convert.ToInt32(row.Cells["cuenta"].Value); string desc = Convert.ToString(row.Cells["descripcion"].Value);

frmSeleccion frm = new frmSeleccion(cuenta, desc); frm.ShowDialog(); }

return true;} [VB.NET]Protected Overloads Overrides Function ProcessCmdKey(ByRef msg As System.Windows.Forms.Message, keyData As System.Windows.Forms.Keys) As Boolean'' Si el control DataGridView no tiene el foco, ' se abandonamos el procedimiento, llamando al metodo base'If (Not dataGridView1.Focused) ThenReturn MyBase.ProcessCmdKey(msg, keyData)End If

'' Si la tecla presionada es distinta al ENTER, ' se abandonamos el procedimiento, llamando al metodo base'If keyData Keys.Enter ThenReturn MyBase.ProcessCmdKey(msg, keyData)End If'' Obtenemos la fila actual 'Dim row As DataGridViewRow = dataGridView1.CurrentRow

If rbMostrarMensaje.Checked Then

MessageBox.Show(String.Format("Se ha seleccionado, Cuenta:'{0}' Descripcion:'{1}'", row.Cells("cuenta").Value, row.Cells("descripcion").Value))

ElseIf rbMostrarForm.Checked Then

Dim cuenta As Integer = CInt(row.Cells("cuenta").Value) Dim desc As String = CStr(row.Cells("descripcion").Value)

Dim frm As New frmSeleccion(cuenta, desc) frm.ShowDialog()

End If

Return TrueEnd Function- 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 ENTERSi las dos validaciones anteriores pasaron, se puede recuperar la fila seleccionada en la grilla, y trabajar con la informacin que esta proporcione.[C#]

[VB.NET]

ListView Seleccin de la filaLa 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#]protected override bool ProcessCmdKey(ref System.Windows.Forms.Message msg, System.Windows.Forms.Keys keyData){ // // Si el control DataGridView no tiene el foco, // se abandonamos el procedimiento, llamando al metodo base // if ((!listView1.Focused)) return base.ProcessCmdKey(ref msg, keyData);

// // Si la tecla presionada es distinta al ENTER, // se abandonamos el procedimiento, llamando al metodo base // if (keyData != Keys.Enter) return base.ProcessCmdKey(ref msg, keyData);

// // Sino hay item seleccinado en la lista // se abandonamos el procedimiento, llamando al metodo base // if(listView1.SelectedItems.Count == 0) return base.ProcessCmdKey(ref msg, keyData);

// // Obtenemos la fila actual // ListViewItem item = listView1.SelectedItems[0];

if (rbMostrarMensaje.Checked) { MessageBox.Show(string.Format("Se ha seleccionado, Cuenta:'{0}' Descripcion:'{1}'", item.Text, item.SubItems[1].Text)); } else if (rbMostrarForm.Checked) { int cuenta = Convert.ToInt32(item.Text); string desc = Convert.ToString(item.SubItems[1].Text);

frmSeleccion frm = new frmSeleccion(cuenta, desc); frm.ShowDialog(); }

return true;} [VB.NET]Protected Overloads Overrides Function ProcessCmdKey(ByRef msg As System.Windows.Forms.Message, keyData As System.Windows.Forms.Keys) As Boolean'' Si el control DataGridView no tiene el foco, ' se abandonamos el procedimiento, llamando al metodo base'If (Not listView1.Focused) ThenReturn MyBase.ProcessCmdKey(msg, keyData)End If

'' Si la tecla presionada es distinta al ENTER, ' se abandonamos el procedimiento, llamando al metodo base'If keyData Keys.Enter ThenReturn MyBase.ProcessCmdKey(msg, keyData)End If

'' Sino hay item seleccinado en la lista' se abandonamos el procedimiento, llamando al metodo base'If listView1.SelectedItems.Count = 0 ThenReturn MyBase.ProcessCmdKey(msg, keyData)End If

'' Obtenemos la fila actual 'Dim item As ListViewItem = listView1.SelectedItems(0)

If rbMostrarMensaje.Checked Then

MessageBox.Show(String.Format("Se ha seleccionado, Cuenta:'{0}' Descripcion:'{1}'", item.Text, item.SubItems(1).Text))

ElseIf rbMostrarForm.Checked Then

Dim cuenta As Integer = CInt(item.Text) Dim desc As String = CStr(item.SubItems(1).Text)

Dim frm As New frmSeleccion(cuenta, desc) frm.ShowDialog()

End If

Return True

End Function[C#]

[VB.NET]

Publicado porLeandro Tuttinien20:4939 comentarios:Etiquetas:DataGridView,WinFormsbado, 20 de marzo de 2010[DataGridView] - ComboBox y evento SelectedIndexChangedIntroduccin

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 eventoCellValueChangedse 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 tipoDataGridViewComboBoxColumn, al eventoSelectedIndexChanged, 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 editandoprivate void dataGridView1_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e){ DataGridViewComboBoxEditingControl dgvCombo = e.Control as DataGridViewComboBoxEditingControl; if (dgvCombo != null) { // // se remueve el handler previo que pudiera tener asociado, a causa ediciones previas de la celda // evitando asi que se ejecuten varias veces el evento // dgvCombo.SelectedIndexChanged -= new EventHandler(dvgCombo_SelectedIndexChanged); dgvCombo.SelectedIndexChanged += new EventHandler(dvgCombo_SelectedIndexChanged); }

}

private void dvgCombo_SelectedIndexChanged(object sender, EventArgs e) { // // se recupera el valor del combo // a modo de ejemplo se escribe en consola el valor seleccionado // ComboBox combo = sender as ComboBox;

Console.WriteLine(combo.SelectedValue);

// // se accede a la fila actual, para trabajr con otor de sus campos // en este caso se marca el check si se cambia la seleccion // DataGridViewRow row = dataGridView1.CurrentRow;

DataGridViewCheckBoxCell cell = row.Cells["Seleccionado"] as DataGridViewCheckBoxCell; cell.Value = true;}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.private void dataGridView1_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e) { if (e.Control is ComboBox) { DataGridViewComboBoxEditingControl dgvCombo = e.Control as DataGridViewComboBoxEditingControl; // // se remueve el handler previo que pudiera tener asociado, a causa ediciones previas de la celda // evitando asi que se ejecuten varias veces el evento // dgvCombo.SelectedIndexChanged -= new EventHandler(dvgCombo_SelectedIndexChanged); dgvCombo.SelectedIndexChanged += new EventHandler(dvgCombo_SelectedIndexChanged); }

}[C#]

[VB.NET]

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.DataGridViewComboBoxEditingControl dgvCombo;

private void dataGridView1_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e){ dgvCombo = e.Control as DataGridViewComboBoxEditingControl; if (dgvCombo != null) { dgvCombo.SelectedIndexChanged += new EventHandler(dvgCombo_SelectedIndexChanged); }

}

private void dvgCombo_SelectedIndexChanged(object sender, EventArgs e) { // // se recupera el valor del combo // a modo de ejemplo se escribe en consola el valor seleccionado // ComboBox combo = sender as ComboBox;

Console.WriteLine(combo.SelectedValue);

// // se accede a la fila actual, para trabajr con otor de sus campos // en este caso se marca el check si se cambia la seleccion // DataGridViewRow row = dataGridView1.CurrentRow;

DataGridViewCheckBoxCell cell = row.Cells["Seleccionado"] as DataGridViewCheckBoxCell; cell.Value = true;}

private void dataGridView1_CellEndEdit(object sender, DataGridViewCellEventArgs e){

if (dgvCombo != null) dgvCombo.SelectedIndexChanged -= new EventHandler(dvgCombo_SelectedIndexChanged);

}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[C#]

[VB.NET]

Publicado porLeandro Tuttinien22:3637 comentarios:Etiquetas:DataGridViewlunes, 1 de marzo de 2010[DataGridView] Clculos Totales en las filas y columnasIntroduccin

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 controlEn 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.private void frmPedidos_Load(object sender, EventArgs e){ // // Se recupera los datos de los productos desde la tabla // dtoProductos datos = ProductoDAL.ProductosGetAll();

// // Se agrega un registro adicional al DataTable, para representar la fila de totales // dtoProductos.ProductosRow rowTotal = datos.Productos.NewProductosRow(); datos.Productos.Rows.Add(rowTotal);

// // Se bindean los datos a la grilla // dataGridView1.AutoGenerateColumns = false; dataGridView1.DataSource = datos; dataGridView1.DataMember = "Productos";

// // Se selecciona la ultima fila de Totales y se marca como readonly // para evitar la seleccion por el usuario // DataGridViewRow row = dataGridView1.Rows[dataGridView1.Rows.Count - 1]; row.ReadOnly = true;

// // Se asigna el evento para detectar los cambios que el usuario realice // dataGridView1.CellValueChanged +=new DataGridViewCellEventHandler(dataGridView1_CellValueChanged); }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 ultima fila para evitar que el usuario la edite.Algo a remarcar es la asignacin del evento manuablemente en la ultima 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.private void dataGridView1_CellValueChanged(object sender, DataGridViewCellEventArgs e){ // // Solo se trabaja ante los cambios en la columan de los checkbox // y el ingreso de una canifad por el usuario // if (dataGridView1.Columns[e.ColumnIndex].Name == "Seleccion" || dataGridView1.Columns[e.ColumnIndex].Name == "Pedido") { decimal totalColumna = 0;

// // Se recorre fila a fila para recalcular el total despues del cambio // foreach (DataGridViewRow row in dataGridView1.Rows) { // // Se selecciona la celda del checkbox // DataGridViewCheckBoxCell cellSelecion = row.Cells["Seleccion"] as DataGridViewCheckBoxCell;

// // Se valida si esta checkeada // if (Convert.ToBoolean(cellSelecion.Value)) { // // Se valida si el usuario ingreso un valor en la celda de pedido // decimal pedido = 0; if (!decimal.TryParse(Convert.ToString(row.Cells["Pedido"].Value), out pedido)) continue;

// // Se realiza el calculo para la fila, asignado el total en la celda "Total" // de la misma // decimal totalFila = Convert.ToDecimal(row.Cells["PrecioUnitario"].Value) * pedido; row.Cells["Total"].Value = totalFila;

// // Se aumula el total de cada una de las filas // totalColumna += totalFila; } }

// // Se toma la ultima fila del total general, asignando el valor acumulado en el calculo // DataGridViewRow rowTotal = dataGridView1.Rows[dataGridView1.Rows.Count - 1]; rowTotal.Cells["Total"].Value = totalColumna;

}}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.private void dataGridView1_CellValidating(object sender, DataGridViewCellValidatingEventArgs e){ if (dataGridView1.Columns[e.ColumnIndex].Name == "Pedido") { // // Si el campo esta vacio no lo marco como error // if (string.IsNullOrEmpty(e.FormattedValue.ToString())) return;

// // Solo se valida ante el ingreso de un valor en el campo // decimal pedido = 0; if (!decimal.TryParse(e.FormattedValue.ToString(), out pedido)) { DataGridViewRow row = dataGridView1.Rows[e.RowIndex]; row.ErrorText = "Debe ingresar un nmero valido"; e.Cancel = true; } }}

//// Este evento es usado al presiona ESC cancelando la edicion// se elimine el mensaje de error en la fila//private void dataGridView1_CellEndEdit(object sender, DataGridViewCellEventArgs e){ dataGridView1.Rows[e.RowIndex].ErrorText = String.Empty;}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.Nonetenga en cuanta este punto cuando use las validaciones[C#]

[VB.NET]

Publicado porLeandro Tuttinien17:1945 comentarios:Etiquetas:DataGridViewmircoles, 20 de enero de 2010[DataGridView] - Uso del DataGridViewComboBoxColumnIntroduccin

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 visualLa 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 esDataPropertyName, 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 propiedadAutoGenerateColumnssea 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 formularioprivate void Form1_Load(object sender, EventArgs e){ // // Asigno los datos del combo de marcas // DataGridViewComboBoxColumn comboboxColumn = dataGridView1.Columns["Marca"] as DataGridViewComboBoxColumn;

comboboxColumn.DataSource = ProductosDAL.GetAllMarca(); comboboxColumn.DisplayMember = "Descripcion"; comboboxColumn.ValueMember = "IdMarca";

// // bindeo los datos de los productos a la grilla // dataGridView1.AutoGenerateColumns = false; dataGridView1.DataSource = ProductosDAL.GetAllProductos();

}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 propiedadAutoGenerateColumnsdefiniendo que solo las columnas creadas en tiempo de diseo sern las visibles.A continuacin se visualizara los mtodo utilizados para cargar los datos en el DataGridViewpublic static List GetAllMarca(){ string sql = @"SELECT IdMarca ,Descripcion FROM Marcas";

List list = new List();

using (OleDbConnection conn = new OleDbConnection(ConfigurationManager.ConnectionStrings["default"].ToString())) {

OleDbCommand command = new OleDbCommand(sql, conn);

conn.Open();

OleDbDataReader reader = command.ExecuteReader();

while (reader.Read()) { list.Add(LoadMarca(reader)); }

return list; }}

private static MarcaEntity LoadMarca(IDataReader reader){ MarcaEntity marca = new MarcaEntity();

marca.IdMarca = Convert.ToInt32(reader["IdMarca"]); marca.Descripcion = Convert.ToString(reader["Descripcion"]);

return marca;}public static List GetAllProductos(){ string sql = @"SELECT [IdProducto] ,[IdMarca] ,[Descripcion] ,[PrecioUnitario] FROM Productos";

List list = new List();

using (OleDbConnection conn = new OleDbConnection(ConfigurationManager.ConnectionStrings["default"].ToString())) {

OleDbCommand command = new OleDbCommand(sql, conn);

conn.Open();

OleDbDataReader reader = command.ExecuteReader();

while (reader.Read()) { list.Add(LoadProducto(reader)); }

return list; }

}

private static ProductoEntity LoadProducto(IDataReader reader){ ProductoEntity producto = new ProductoEntity();

producto.IdProducto = Convert.ToInt32(reader["IdProducto"]);

producto.IdMarca = Convert.ToInt32(reader["IdMarca"]); producto.Descripcion = Convert.ToString(reader["Descripcion"]);

producto.PrecioUnitario = Convert.ToDecimal(reader["PrecioUnitario"]);

return producto;}[C#]

[VB.NET]

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 descuentoprivate void Form1_Load(object sender, EventArgs e){ // // Asigno los datos del combo de marcas // DataGridViewComboBoxColumn comboboxColumn = dataGridView1.Columns["Marca"] as DataGridViewComboBoxColumn;

comboboxColumn.DataSource = ProductosDAL.GetAllMarca(); comboboxColumn.DisplayMember = "Descripcion"; comboboxColumn.ValueMember = "IdMarca";

// // Asigno los datos del combo de descuentos // DataGridViewComboBoxColumn dgccomboDescuento = dataGridView1.Columns["Descuento"] as DataGridViewComboBoxColumn;

dgccomboDescuento.DataSource = ProductosDAL.GetAllDescuentos(); dgccomboDescuento.DisplayMember = "Descripcion"; dgccomboDescuento.ValueMember = "IdDescuento";

// // bindeo los datos de los productos a la grilla // dataGridView1.AutoGenerateColumns = false; dataGridView1.DataSource = ProductosDAL.GetAllProductos();

}Pero lo mas importante es ver como se trabaja con el combo, detectando un cambio en el tem y realizando el calculo del descuento.private void dataGridView1_CellValueChanged(object sender, DataGridViewCellEventArgs e){

if (dataGridView1.Columns[e.ColumnIndex].Name == "Descuento") { // // se obtiene el valor seleccionado en el combo // DataGridViewComboBoxCell combo = dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex] as DataGridViewComboBoxCell;

int idDescuento = Convert.ToInt32(combo.Value);

// // se recupera por el id la info del descuento // DescuentoEntity descuento = ProductosDAL.GetDescuentosById(idDescuento);

// // se calcula el descuento // DataGridViewCell cellPrecioUnitario = dataGridView1.Rows[e.RowIndex].Cells["Precio"]; DataGridViewCell cellPrecioFinal = dataGridView1.Rows[e.RowIndex].Cells["PrecioFinal"];

decimal valordescontar = (descuento.Porcentaje * Convert.ToDecimal(cellPrecioUnitario.Value)) / 100;

cellPrecioFinal.Value = Convert.ToDecimal(cellPrecioUnitario.Value) - valordescontar; }}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.[C#]

[VB.NET]

Publicado porLeandro Tuttinien10:55181 comentarios:Etiquetas:C#,DataGridView,VB.NETdomingo, 3 de enero de 2010[DataGridView] Pasaje de informacin entre grids en distintos formularioIntroduccin

Este artculo es consecuencia de otros descriptos con anterioridadC# Comunicar formularios de forma desacopladaComo 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 complejaEste 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.interface IAddItem{ void AddNewItem(DataGridViewRow row);}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.public partial class Form1 : Form, IAddItem{ public Form1() { InitializeComponent(); }

private void button1_Click(object sender, EventArgs e) { Form2 formAdd = new Form2(); formAdd.Show(this);

}

#region IAddItem Members

public void AddNewItem(DataGridViewRow row) { string item = row.Cells["item"].Value.ToString(); string desc = row.Cells["Desc"].Value.ToString();

this.dataGridView1.Rows.Add(new []{ item, desc });

}

#endregion

}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:private void button1_Click(object sender, EventArgs e){ DataGridViewRow row = this.dataGridView1.SelectedRows[0] as DataGridViewRow;

IAddItem parent = this.Owner as IAddItem; parent.AddNewItem(row);

this.Close();}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.[C#]

[VB.NET]

Publicado porLeandro Tuttinien20:2047 comentarios:Etiquetas:C#,DataGridView,WinFormjueves, 10 de diciembre de 2009[DataGridView] Parte 2 Edicin de celda con form PopUp para la seleccin de tem - KeyDownEl 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.private void dataGridView1_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e){ DataGridViewTextBoxEditingControl dText = (DataGridViewTextBoxEditingControl)e.Control;

dText.KeyDown -= new KeyEventHandler(dText_KeyDown); dText.KeyDown += new KeyEventHandler(dText_KeyDown);}

void dText_KeyDown(object sender, KeyEventArgs e){ int rowIndex = ((System.Windows.Forms.DataGridViewTextBoxEditingControl)(sender)).EditingControlRowIndex;

if (e.Alt && e.KeyCode == Keys.D) { frmSeleccionarProducto form = new frmSeleccionarProducto();

form.ShowDialog();

Producto productoSeleccionado = form.ProductSelected;

DataGridViewRow row = dataGridView1.Rows[rowIndex]; row.Cells["IdProducto"].Value = productoSeleccionado.IdProducto; row.Cells["Descripcion"].Value = productoSeleccionado.Descripcion; row.Cells["precio"].Value = productoSeleccionado.Precio;

dataGridView1.EndEdit(); } }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.private void dataGridView1_CellDoubleClick(object sender, DataGridViewCellEventArgs e){ DataGridViewRow row = dataGridView1.SelectedRows[0];

this.ProductSelected = new Producto() { IdProducto = Convert.ToInt32(row.Cells["IdProducto"].Value), Descripcion = Convert.ToString(row.Cells["Descripcion"].Value), Precio = Convert.ToDecimal(row.Cells["precio"].Value), };

this.Close();}[C#]

[VB.NET]

Publicado porLeandro Tuttinien20:388 comentarios:Etiquetas:C#,DataGridView,WinForm[DataGridView] Parte 1 Valor de celda Condicional usando CellFormattingEl 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 debeprivate void dataGridView1_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e){ DataGridViewColumn currentColumn = dataGridView1.Columns[e.ColumnIndex];

if (currentColumn.Name == "Fracciona") { DataGridViewRow currentRow = dataGridView1.Rows[e.RowIndex]; DataRowView data = currentRow.DataBoundItem as DataRowView;

if (data == null) return;

if(Convert.ToBoolean(data["fracc"])) currentRow.Cells["tipoventa"].Value = Convert.ToString(data["FORM_VENT"]); else currentRow.Cells["tipoventa"].Value = Convert.ToString(data["PRESENTACI"]); }}En este caso la lgica principal se encuentra en el eventoCellFormatting, 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 propiedadDataPropertyNamepero 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 siguienteprivate DataTable GetDataTable(){ DataTable dt = new DataTable();

dt.Columns.Add("fracc", typeof(bool)); dt.Columns.Add("PRESENTACI"); dt.Columns.Add("FORM_VENT");

DataRow row = dt.NewRow(); row["fracc"] = true; row["PRESENTACI"] = "PRESENTACI 1"; row["FORM_VENT"] = "FORM_VENT 1"; dt.Rows.Add(row);

row = dt.NewRow(); row["fracc"] = false; row["PRESENTACI"] = "PRESENTACI 2"; row["FORM_VENT"] = "FORM_VENT 2"; dt.Rows.Add(row);

row = dt.NewRow(); row["fracc"] = false; row["PRESENTACI"] = "PRESENTACI 3"; row["FORM_VENT"] = "FORM_VENT 3"; dt.Rows.Add(row);

row = dt.NewRow(); row["fracc"] = true; row["PRESENTACI"] = "PRESENTACI 4"; row["FORM_VENT"] = "FORM_VENT 4"; dt.Rows.Add(row);

return dt;

}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 filaprivate void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e){

DataGridViewColumn currentColumn = dataGridView1.Columns[e.ColumnIndex];

if (currentColumn.Name == "Fracciona") { DataGridViewCheckBoxCell currentCell = dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex] as DataGridViewCheckBoxCell;

DataGridViewRow currentRow = dataGridView1.Rows[e.RowIndex]; DataRowView data = currentRow.DataBoundItem as DataRowView;

if (data == null) return;

if (Convert.ToBoolean(currentCell.Value)) currentRow.Cells["tipoventa"].Value = Convert.ToString(data["FORM_VENT"]); else currentRow.Cells["tipoventa"].Value = Convert.ToString(data["PRESENTACI"]);

dataGridView1.EndEdit(); }}[C#]

[VB.NET]

Publicado porLeandro Tuttinien18:1025 comentarios:Etiquetas:C#,DataGridViewmircoles, 2 de diciembre de 2009[DataGridView] KeyPress detectar ENTER y bsquedaEl 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 celdaSe 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.private void dataGridView1_CellEnter(object sender, DataGridViewCellEventArgs e){ dataGridView1.BeginEdit(false);}

private void dataGridView1_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e){ DataGridViewTextBoxEditingControl dText = (DataGridViewTextBoxEditingControl)e.Control; dText.KeyUp -= new KeyEventHandler(text_KeyUp); dText.KeyUp += new KeyEventHandler(text_KeyUp);}

void text_KeyUp(object sender, KeyEventArgs e){ int rowIndex = ((System.Windows.Forms.DataGridViewTextBoxEditingControl)(sender)).EditingControlRowIndex; if (e.KeyCode == Keys.Enter) { int valueEntered = Convert.ToInt32(dataGridView1.Rows[rowIndex - 1].Cells["cuenta"].Value);

dataGridView1.Rows[rowIndex - 1].Cells["descripcion"].Value = this.Search(valueEntered); }}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 LinQprivate DataTable GetDataTable(){ DataTable dt = new DataTable();

dt.Columns.Add("cuenta"); dt.Columns.Add("descripcion");

DataRow row = dt.NewRow(); row["cuenta"] = "1001"; row["descripcion"] = "cuenta 1001"; dt.Rows.Add(row);

row = dt.NewRow(); row["cuenta"] = "1002"; row["descripcion"] = "cuenta 1002"; dt.Rows.Add(row);

row = dt.NewRow(); row["cuenta"] = "1003"; row["descripcion"] = "cuenta 1003"; dt.Rows.Add(row);

return dt;

}

private string Search(int cuenta){ string descripcion = (from item in this.GetDataTable().AsEnumerable() where Convert.ToInt32(item["cuenta"]) == cuenta select item["descripcion"].ToString()).FirstOrDefault();

return descripcion;}[C#]

IntroduccinEste es un ejemplo de cmo utilizar el componente Listview de CSharp. En este artculo te muestro como agregar y eliminar datos a dicho componente, y tambin el uso deTimeSpan, que en este ejemplo lo utilizo para calcular la edad.Bueno espero que les sea de su utilidad.Diseo del Formulario

Nota:Agregar un Label y en su propiedad Name colocar lblcodigo y en la propiedad Text colocar el valor 1, esto nos permitir autogenerar el cdigo.Ac les muestro el Cdigo:using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Drawing;using System.Text;using System.Windows.Forms;

namespace WindowsApplication2{ public partial class FrmListView : Form { public FrmListView() { InitializeComponent(); } //El Label lblcodigo est oculto, y en su propiedad text colocar 1 para poder generar //el cdigo... private void btnagregar_Click(object sender, EventArgs e) {

int edad; string f1;

f1 = dtfecnaci.Value.ToShortDateString(); TimeSpan diferencia = Convert.ToDateTime(DateTime.Now.ToShortDateString()) - Convert.ToDateTime(f1); edad = Convert.ToInt16(diferencia.Days.ToString()) / 365; //aca obtengo la edad

ListViewItem elemeneto = new ListViewItem(); elemeneto = listView1.Items.Add(lblcodigo.Text); elemeneto.SubItems.Add(txtapellidos.Text); elemeneto.SubItems.Add(txtnombres.Text); elemeneto.SubItems.Add(edad.ToString()); elemeneto.SubItems.Add(txtelefono.Text); elemeneto.SubItems.Add(cbosexo.Text); Limpiar(); GeneraCodigo(); }

private void FrmListView_Load(object sender, EventArgs e) { listView1.Columns.Add("Cdigo", 70, HorizontalAlignment.Left); listView1.Columns.Add("Apellidos", 150, HorizontalAlignment.Left); listView1.Columns.Add("Nombre(s)", 150, HorizontalAlignment.Left); listView1.Columns.Add("Edad", 50, HorizontalAlignment.Left); listView1.Columns.Add("Telfono", 80, HorizontalAlignment.Left); listView1.Columns.Add("Sexo", 90, HorizontalAlignment.Left); listView1.View = View.Details;

}

private void Limpiar() { foreach (Control obj in this.groupBox1.Controls) { if (obj is TextBox) { obj.Text = ""; } txtapellidos.Focus(); } }

private void GeneraCodigo() { int c; int nuevo; string elemento; c = listView1.Items.Count - 1; elemento = listView1.Items[c].Text.ToString(); nuevo = Convert.ToInt16(elemento) + 1; lblcodigo.Text = nuevo.ToString();

} private void SoloLetras(object sender, KeyPressEventArgs e) { int keyascii = Convert.ToInt32(e.KeyChar); if ((keyascii >= 65 && keyascii = 97 && keyascii = 48 && keyascii 0) { listView1.Items.Remove(listView1.Items[numindex]); }

if (Convert.ToInt16(listView1.Items.Count) == 0) { lblcodigo.Text = "1"; } }

private void button1_Click(object sender, EventArgs e) { this.Close(); }

}}Espero que sea de su utilidad AtteShami....