Foros del Web » Programación para mayores de 30 ;) » .NET »

VB.2005 Cargar ListView en tiempo real

Estas en el tema de VB.2005 Cargar ListView en tiempo real en el foro de .NET en Foros del Web. Hola Foreros, tengo un problemilla con la carga de un ListView. Tengo un programa que carga una pantalla de inicio que me lleva a una ...
  #1 (permalink)  
Antiguo 19/03/2014, 12:39
vejin666
Invitado
 
Mensajes: n/a
Puntos:
VB.2005 Cargar ListView en tiempo real

Hola Foreros, tengo un problemilla con la carga de un ListView.

Tengo un programa que carga una pantalla de inicio que me lleva a una segunda pantalla donde se encuentra un listado de clientes cargados en un ListView. El problema me llega cuando cargo muchos datos, que el programa se queda "colgado" en la primera pantalla hasta que el ListView se carga por completo.

Quisiera que se realizase una carga en "tiempo real" del ListView, es decir, que el usuario vea que se estan cargando datos y que el programa no se ha colgado.

¿Hay alguna forma de hacerlo?

Mil gracias!
  #2 (permalink)  
Antiguo 19/03/2014, 13:56
Avatar de gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.324
Antigüedad: 17 años
Puntos: 2658
Respuesta: VB.2005 Cargar ListView en tiempo real

Es un problema habitual del ListView, porque el mismos se va refrescando mientras lo cargas dinámicamnete. Pero tiene una solución: tiene un método que permite suspender el refresh...
LisView.BeginUpdate()
y su compañero:
LisView.EndUpdate()
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #3 (permalink)  
Antiguo 22/03/2014, 04:51
vejin666
Invitado
 
Mensajes: n/a
Puntos:
Respuesta: VB.2005 Cargar ListView en tiempo real

Muchisimas gracias por tu rapida respuesta, pero no consigo que funcione... con los eventos que me has indicado, con listview.beginupdate() el listview no muestra ninguna informacion, y con listview.endupdate() hace lo mismo que antes...

Creo que no entiendo muy bien su funcionamiento. ¿Podrias explicarme mas sobre esos eventos?

Gracias!
  #4 (permalink)  
Antiguo 22/03/2014, 07:01
Avatar de gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.324
Antigüedad: 17 años
Puntos: 2658
Respuesta: VB.2005 Cargar ListView en tiempo real

¿Y lo mandaste a refrescar?

Postea el código completo de la carga (y por favor, usa el Highlight "VBScript")
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #5 (permalink)  
Antiguo 30/03/2014, 09:22
vejin666
Invitado
 
Mensajes: n/a
Puntos:
Respuesta: VB.2005 Cargar ListView en tiempo real

Hola gnzsoloyo, lamento el haber tardado tanto en contestar. El codigo para cargar el ListView lo tengo en un Sub.

Código vb:
Ver original
  1. Sub CargarDatos()
  2.         Dim i As Integer
  3.         Dim contador As Integer
  4.         Try
  5.             com.CommandText = "Select count(*) from clientes"
  6.             If cn.State = ConnectionState.Closed Then
  7.                 cn.Open()
  8.             End If
  9.             com.CommandText = "Select * from clientes order by ID"
  10.             datos = com.ExecuteReader
  11.  
  12.             ListView1.Clear()
  13.  
  14.             With ListView1.Columns
  15.                 .Add("ID", 30, HorizontalAlignment.Center)
  16.                 .Add("Nombre", 75, HorizontalAlignment.Center)
  17.                 .Add("Apellidos", 100, HorizontalAlignment.Center)
  18.                 .Add("Teléfono", 70, HorizontalAlignment.Center)
  19.                 .Add("Dirección", 150, HorizontalAlignment.Center)
  20.                 .Add("Población", 90, HorizontalAlignment.Center)
  21.                 .Add("Provincia", 90, HorizontalAlignment.Center)
  22.             End With
  23.             contador = 0
  24.             Do While datos.Read
  25.                 ListView1.BeginUpdate()
  26.                 Dim elem As New ListViewItem
  27.                 elem.ImageIndex = 0
  28.                 elem.Text = datos.GetValue(0)
  29.                 elem.Tag = datos.GetValue(0)
  30.                 For i = 1 To datos.FieldCount - 1
  31.                     elem.SubItems.Add(datos.GetValue(i))
  32.                 Next
  33.                 If contador = 0 Then
  34.                     elem.BackColor = Color.Beige
  35.                     contador = contador + 1
  36.                 Else
  37.                     elem.BackColor = Color.Bisque
  38.                     contador = contador - 1
  39.                 End If
  40.                 ListView1.Items.Add(elem)
  41.                 ListView1.EndUpdate()
  42.             Loop
  43.  
  44.             ListView1.View = View.Details
  45.             ListView1.FullRowSelect = True
  46.             ListView1.GridLines = True
  47.         Catch ex As Exception
  48.             MessageBox.Show(ex.Message)
  49.         End Try
  50.         datos.Close()
  51.         cn.Close()
  52.     End Sub

Como puedes ver uso el
Código vb:
Ver original
  1. ListView1.BeginUpdate()
al entrar el el bucle y el
Código vb:
Ver original
  1. ListView1.EndUpdate()
antes de salir del bucle.

Como te dije antes me sigue sin funcionar, asi que creo que no entiendo bien como funcionana esos eventos.
  #6 (permalink)  
Antiguo 30/03/2014, 19:59
Avatar de gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.324
Antigüedad: 17 años
Puntos: 2658
Respuesta: VB.2005 Cargar ListView en tiempo real

Tendría que buscar un poco en la documentación de un par de proyectos sobre los que trabajé ese problema, pero si mal no recuerdo ahora, hay problemas cuando invocas al .BeginUpdate() y .EndUpdate() dentro de un subproceso.
Recuerdo que por un lado, estos dos métodos debían llamarse antes y después de llamar al Sub, y no dentro de él. Y por otro lado, deben implementarse por medio de delegados.
Verifica lo primero, mientras yo buco la documentación de esos casos.
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #7 (permalink)  
Antiguo 31/03/2014, 05:52
Avatar de gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.324
Antigüedad: 17 años
Puntos: 2658
Respuesta: VB.2005 Cargar ListView en tiempo real

Bueno, encontré uno de los proyectos donde trabajé ese tema, y la cosa, pese a mi recuerdo, era exactamente como la estás planteando, pero con un pequeño agregado...
Primero algunos consejos:
1) No acoples la generación de la visualizacion a la base de datos. Crea una clase específica para administrar la relación de la aplicación con la base, y ponle todas las llamadas allí (obviamente creando una para cada caso nuevo que necesites).
2) No configures la visualización del ListView en el mismo método que lo carga. Son acciones y conceptos diferentes. Separalo al menos en dos: Uno para confirurar el control y otro para cargarlo.
3) No manipules directamente el control en el Sub. Pasalo como parámetro y cargalo así. Incluso más, te conviene pasar el control y la tabla de datos (no un reader, por favor, un DataSet o DataTable) para hacer toda la tarea.

Bien, este sería el código original (extirpadas todas las partes no relevantes) de uno de los usados:
Código vb:
Ver original
  1. Private Sub Mostrar(ByVal List As ListView, ByRef DS() As DataRow)
  2.         ' -----------------------------------------------------------------
  3.        Dim objListItem As New ListViewItem
  4.         ' -------------------------------------------------------------------
  5.        List.BeginUpdate()
  6.         With List
  7.             .Items.Clear()
  8.             Dim contar As Integer = 0
  9.             For Each drw As DataRow In DS
  10.                 objListItem = .Items.Add(valor_A_Ingresar, 0)
  11.                 ' Valores a ingresar en cada columna
  12.                objListItem.SubItems.Add(drw.Item(0).ToString)
  13.                 objListItem.SubItems.Add(drw.Item(1).ToString)
  14.                 objListItem.SubItems.Add(drw.Item(3).ToString)
  15.                 objListItem.SubItems.Add(drw.Item(4).ToString)
  16.                 objListItem.SubItems.Add(drw.Item(5).ToString)
  17.         End With
  18.         ' -----------------------------------------------------------------
  19.        List.EndUpdate()
  20.         ' Esto es para que la aplicación refresque
  21.        Application.DoEvents()
  22.         ' Esto es porque primero oculto el control, a fin de que el refresco del mismo no lo haga más lento.
  23.        LV.Show()
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)

Última edición por gnzsoloyo; 31/03/2014 a las 06:37
  #8 (permalink)  
Antiguo 31/03/2014, 15:49
vejin666
Invitado
 
Mensajes: n/a
Puntos:
Respuesta: VB.2005 Cargar ListView en tiempo real

Cita:
Iniciado por gnzsoloyo Ver Mensaje
1) No acoples la generación de la visualizacion a la base de datos. Crea una clase específica para administrar la relación de la aplicación con la base, y ponle todas las llamadas allí (obviamente creando una para cada caso nuevo que necesites).
2) No configures la visualización del ListView en el mismo método que lo carga. Son acciones y conceptos diferentes. Separalo al menos en dos: Uno para confirurar el control y otro para cargarlo.
3) No manipules directamente el control en el Sub. Pasalo como parámetro y cargalo así. Incluso más, te conviene pasar el control y la tabla de datos (no un reader, por favor, un DataSet o DataTable) para hacer toda la tarea.
Hola otra vez gnzsoloyo, he seguido tus consejos 2 y 3 (excepto lo de pasar tambien el dataset, esta "Under Construction"), he metido la configuracion de visualizacion del ListView en un Sub aparte, y he enviado por cabecera el ListView en vez de trabajar con el directamente, he colocado los ListView.BeginUpdate() y ListView.EndUpdate() fuera del sub (antes y despues respectivamente de la llamada al sub de carga) y noto una mejoria en la visualiacion de la pantalla, pero he probado a meter un Threading.Thread.Sleep(500) dentro del loop para comprobar la carga.
Código vb:
Ver original
  1. Do While datos.Read
  2.  
  3.                 Threading.Thread.Sleep(500)
  4.                
  5.                 Dim elem As New ListViewItem
  6.                 elem.ImageIndex = 0
  7.                 elem.Text = datos.GetValue(0)
  8.                 elem.Tag = datos.GetValue(0)
  9.                 For i = 1 To datos.FieldCount - 1
  10.                     elem.SubItems.Add(datos.GetValue(i))
  11.                 Next
  12.                 If contador = 0 Then
  13.                     elem.BackColor = Color.Beige
  14.                     contador = contador + 1
  15.                 Else
  16.                     elem.BackColor = Color.Bisque
  17.                     contador = contador - 1
  18.                 End If
  19.                 tabla.Items.Add(elem)
  20.             Loop

Al meter el Sleep vuelve a quedarse la pantalla congelda, ¿el metodo sleep provoca esos efectos?

Una cosa mas, tu consejo numero 1 no lo entiendo bien, ¿Te refieres a que haga todas las llamadas a la base de datos y cargue un DataSet o DataTable en un sub a parte y luego lo envie a la visualizacion?

Muchas gracias por tu infinita paciencia.

Etiquetas: listview, real, tiempo
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 13:24.