Introducción
En este articulo tratare de mostrar como se hace uso de ListView de manera que se puedan visualizar los registros, y manipularlos, en este caso se editara individualmente un ítem de la lista, y se trabajara mediante la el pasaje de la selección a otro ListView.
Algunas propiedades importante que se han usado en el ejemplo son
- View= Details, permite definir el layout de los ítem dentro del ListView, por tratarse de ítem con estilo de grilla, se usa el modo de detalle.
- FullRowSelect = True, esta propiedad permite que al seleccionar un ítem este sea se resalte a lo largo del registro
- HideSelection = False, cuando el control pierde el foco este mantiene un un control griseada la selección activa.
La creación de las columnas fue realizada en tiempo de diseño, para los cual se hizo uso las opciones mostradas en la siguiente imagen
Carga del ListView
El primer paso que se realizaría será la carga de los ítems dentro del control.
private void Form1_Load(object sender, EventArgs e) { DataTable dt = ObtenerDatos(); foreach (DataRow row in dt.Rows) { ListViewItem item = new ListViewItem(Convert.ToString(row["id"])); item.SubItems.Add(Convert.ToString(row["descripcion"])); item.SubItems.Add(Convert.ToString(row["precio"])); lswProductos.Items.Add(item); } }
A modo de ejemplo en este caso se ha usado como origen de dato un DataTable cargado manualmente desde código:
private DataTable ObtenerDatos() { DataTable dt = new DataTable(); dt.Columns.Add("Id"); dt.Columns.Add("descripcion"); dt.Columns.Add("precio"); DataRow row = dt.NewRow(); row["id"] = 1; row["descripcion"] = "Prod 1"; row["precio"] = 140; dt.Rows.Add(row); row = dt.NewRow(); row["id"] = 2; row["descripcion"] = "Prod 2"; row["precio"] = 30; dt.Rows.Add(row); row = dt.NewRow(); row["id"] = 3; row["descripcion"] = "Prod 3"; row["precio"] = 60; dt.Rows.Add(row); row = dt.NewRow(); row["id"] = 4; row["descripcion"] = "Prod 4"; row["precio"] = 110; dt.Rows.Add(row); return dt; }
En este caso por cada ítem del origen de datos se recorrer en un ciclo del foreach y se van creando los ListViewItem que definen cada registro.
A cada ítem del ListView se le definen sus SubItems que representaran las columnas.
Debe aclararse que la primer columna en el ListView es representada por el propio ListViewItem, es por eso que no hay un SubItem que represente la columna “Id”.
Pasaje de ítems entre ListView
Una de las acciones mas comunes es la selección de ítems para su posterior trabajo con estos datos.
Es por eso que en el ejemplo se veras dos botones que permitirán pasar los registros entre controles.
private void btnAgregar_Click(object sender, EventArgs e) { foreach(ListViewItem item in lswProductos.SelectedItems) { lswProductos.Items.Remove(item); lswProductosSeleccionados.Items.Add(item); } } private void btnQuitar_Click(object sender, EventArgs e) { foreach (ListViewItem item in lswProductosSeleccionados.SelectedItems) { lswProductosSeleccionados.Items.Remove(item); lswProductos.Items.Add(item); } }
Como se observa en cada caso las listas son recorridas en sus ítems seleccionados, procediendo a la eliminación del registro y su posterior agregado en la segunda lista.
Edición del ítem seleccionado
Algo que será raro encontrar en el ListView, es que este no posee un método claro para poder detectar cual es el registro o ítem actualmente seleccionado, todas las propiedades hacen referencia a un conjunto de registros.
private void lswProductos_MouseDoubleClick(object sender, MouseEventArgs e) { ListViewItem item = lswProductos.GetItemAt(e.X, e.Y); if (item != null) { txtId.Text = item.Text; txtDescripcion.Text = item.SubItems[1].Text; txtPrecio.Text = item.SubItems[2].Text; } }
El evento MouseDoubleClick posee en sus argumentos dos propiedades que especifican las coordenadas del cursor, las cuales combinadas a el método GetItemAt() permiten seleccionar que ítem se ha pulsado, y con este la edición del mismo
[C#]
|
[VB.NET]
|
Hola Leandro,
ResponderEliminarhaciendo doble click funciona correctamente, pero como hago cuando el usuario seleccione un item determinado a travez de la tecla "enter", podrias ayudarme por favor ya que le he dado vueltas y no consigo hacerlo, muchisimas gracias de antemano. ROBERTO IZURIETA
hola, Roberto
ResponderEliminarmira publique un ejemplo de codigo sobre el tema
[Winforms] Seleccionar Fila con ENTER – DataGridView y ListView
no esta completo aun en la explicacion del articulo, pero si tienes el codigo para descargar
espero te sea de utilidad
saludos
Muchas gracias Leandro por tu respuesta y servicialidad.
ResponderEliminarYa que lo necesitaba urgente, se me ocurrio una solución en base a la clase del evento (MouseDoubleClick) del control ListView que pusistes como ejemplo.
La solución lo hice con el evento (KeyDown) del control ListView. Aquí te dejo el código de referencia:
private void lswProductos_KeyDown(object sender, MouseEventArgs e)
{
ListViewItem item = lswProductos.GetItemAt(lswProductos.FocusedItem.Position.X, lswProductos.FocusedItem.Position.Y);
if (item != null & e.KeyCode == Keys.Enter)
{
txtId.Text = item.Text;
txtDescripcion.Text = item.SubItems[1].Text;
txtPrecio.Text = item.SubItems[2].Text;
}
}
Controla que la tecla presionada sea ENTER, y le paso la posición a travez de (FocusedItem.Position).
Saludos y que tengas un buen día.
Roberto Izurieta Moreno
Perdón hay un error tipográfico en la declaración de la clase:
ResponderEliminarFALSO:
private void lswProductos_KeyDown(object sender, MouseEventArgs e)
CORRECTO:
private void lswProductos_KeyDown(object sender, KeyEventArgs e)
Hasta pronto.
Roberto Izurieta Moreno.
Hola Leandro,
ResponderEliminarEstoy haciendo un foreach sobre una tabla sql con un listview, en realidad es un filtro para una busqueda sobre la tabla y me esta generando un error de pila.
genera esto:
"Excepción no controlada del tipo 'System.StackOverflowException' en mscorlib.dll"
Me das una mano...
gracias!!
hola Santiago
ResponderEliminarDisculpa la demora en la respuesta
La verdad es algo complidado decir que puede estar sucediendo sin poder ver el codigo que usas para cargar la lista.
Por ahi podrias hacer la pregunta en el foro de MSDN, alli participo activamente, y sino soy yo quien responde seguro alguien mas brindara la ayuda
Foros MSDN
saludos
Me ha salvado, Sr. Leandro! Mis items no se añadían a mi Listview porque olvidaba agregarle columnas y usar el objeto ListViewItem.
ResponderEliminarHola Leandro,
ResponderEliminarAProvechando este articulo queria preguntarte como puedo seleccionar un Item de mi listview y luego borrarlo con un boton. He intentado de varias maneras y ya se que ListView NO TIENEN UN METODO PARA TOMAR UNA LINEA y borrarla.
Trate de recuperar parte del codigo que dejaste en este blog, precisamente la parte:
'ListView1.Items.Clear()
'private void lswProductos_MouseDoubleClick(object sender, MouseEventArgs e)
{
ListViewItem item = lswProductos.GetItemAt(e.X, e.Y);
if (item != null)
{
txtId.Text = item.Text;
txtDescripcion.Text = item.SubItems[1].Text;
txtPrecio.Text = item.SubItems[2].Text;
}
}
Pero no puede adaptarlo a lo que quiero.
Gracias
hola Federico
ResponderEliminarpero si hay eventos de seleccion, podrias usar el SelectedIndexChanged
ListView Events
o sea los eventos son del item del listview
con la seleccion determinas que item se selecciono y despues usas el Remove()
How to: Add and Remove Items with the Windows Forms ListView Control
saludos
hola leandro .. hay alguna forma de hacer mas ancho el scrolbar de un listview. es que estoy desarrollando un sistema para pantalla tactil y la pantalla es de 7" , y muestro mucha info en listview,, si hay alguna forma te agradeceria mucho oalguna idea..
ResponderEliminarhola leandro buenos dias: hay alguna form,a d ehacer mas ancho el ScrollBar de Listview., lo ocupo para un sistema de pantalla tactil
ResponderEliminarhola
ResponderEliminarla verdad nunca he implementado algo asi, si es un desarrollo tactil deberias evaluar usar WPF
para winform quizas debas ver si algun api de windows permite lograrlo
Winforms - Adjust width of vertical scrollbar on CheckedListBox
saludos
Hola.
ResponderEliminarExiste alguna forma de indicarle qué fila seleccionar por código?
En el datagridView existe el ".Rows[indice].Selected=true", cómo se haría esto en un ListView?
Por otra parte, tengo un DatagridView y no sé si convertir el control a ListView, consume menos recursos un ListView que un datagridView? gracias.
hola joan
ResponderEliminarninguno de los dos consume mas recursos del otro, cada uno tinee su funcionalidad, quizas si el grid se considera mas pesado es porque tiene mas funcionalidad que el listview
en el listview lo que seleccionas es un item
ListViewItem.Selected Property
saludos
Hola buenas noches,Tengo dos forms,en el primero se llena la lista y en el segundo se muestran los Items seleccionados,y quiero que en el segudo form al elegir uno y eliminarlo se elimine tambien del primer form,como puedo hacerlo?
ResponderEliminarHola tengo una duda en establecer el ancho de una columna de un listview cuando esta en modo TILE. Le paso como parametro en ancho lvw.Columns.Add(texto,ancho,alineamiento) pero no funciona... Mi listview solo va a tener una sola columna
ResponderEliminarHola Leandro quisiera poner dos lineas de texto en una elemento del listview no se si me explico, que la linea del listview se vea algo como
ResponderEliminar_________________________________________________________________
1 x 10 lia $10
galletita
_________________________________________________________________
Gracias
Hola Leandro, y si en el listview1 el numero de datos es a gusto del usuario como hago para crear el private DataTable ObtenerDatos() ya que ahi esta llamando a todos los elementos de forma manual y pues se supone que yo no sé cuales son los valores que introduzca el usuario y cuantos son, gracias de antemano
ResponderEliminarHola Leandro. Necesito poner los items de un listbox en celdas vacias de una columna de datagridview. Hasta ahora sólo he logrado que se cargue la primera en la primer celda vacia, pero necesito que llene todas las celdas vacias con los valores que estan el en listbox.
ResponderEliminarte dejo el código que hasta ahora tengo
Public Sub inserta()
Dim Celda
For i = 0 To FrmSorteo.LstSorteo.Items.Count - 1
' Recorremos las filas
For Each row As DataGridViewRow In FrmSorteo.DgvJuga.Rows
If (row.IsNewRow) Then
' Si es la fila de nuevos registros (la última fila en blanco del control DataGridView), continuamos el bucle.
Continue For
End If
' Recorremos las celdas de cada fila
For Each col As DataGridViewCell In row.Cells ' Obtenemos el valor de la celda
Dim value As Object = col.Value
If ((value Is Nothing) OrElse (value Is DBNull.Value)) Then ' Al menos una celda está vacía.
Dim rowIndex As Integer = rowIndex
Dim columnIndex As Integer = 6 ' Seleccionamos la celda vacía.
FrmSorteo.DgvJuga.CurrentCell = FrmSorteo.DgvJuga.Rows(rowIndex).Cells(columnIndex)
Celda = FrmSorteo.DgvJuga.CurrentCell
' Abandonamos el procedimiento
'FrmSorteo.DgvJuga.Rows(i).Cells(6).Value = FrmSorteo.LstSorteo.Items(i).ToString
'FrmSorteo.LstSorteo.Items.Clear()
Celda.value = FrmSorteo.LstSorteo.Items(i).ToString
End If
Next
Return
Next
Next i
End Sub