Datapayasadas

julio 28, 2008

Evitando el parpadeo molesto en los ListView

Filed under: C# — Etiquetas: , — Matías @ 10:06 am

Buenas,

No se si habrán notado que, por lo general, al actualizar frecuentemente un ListView (al menos en .Net Framework 2.0) se puede apreciar cierto parpadeo que puede llegar a resulta bastante molesto.
La situación rara vez se soluciona utilizando los métodos BeginUpdate() y EndUpdate(), incluso pueden empeorarla.

Investigando un poquito encontré en donde radica el problema: parece ser que la sobrecarga del método Update() del control está mal implementada, entonces actúa como si fuera un Refresh().

Un Update() debería hacer que el control redibuje solo la región invalidada, mientras que un Refresh() debería redibujar toda el área asignada al control, es decir, el control en su totalidad.

Por decirlo de algún modo, si queremos cambiar el color de fondo de un item en particular (propiedad BackColor), solo ese item debería ser redibujado. Desafortunadamente, esto no sucede … o mejor dicho, sucede pero no como debería; el ListView intenta redibujar toda la superficie a pesar de que solo hemos modificado un item.

Afortunadamente existe una forma de evitar esto, solo debemos hacer lo siguiente:

public class ListViewM : System.Windows.Forms.ListView
{
    public ListViewM()
    {
        // Activamos el DoubleBuffering
        // http://en.wikipedia.org/wiki/Double_buffering
        this.SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.AllPaintingInWmPaint, true);

        // Activamos el evento OnNotifyMessage, asi tenemos la oportunidad
        // de filtrar los mensajes de Windows antes de que lleguen al WndProc
        // del formulario
        this.SetStyle(ControlStyles.EnableNotifyMessage, true);
    }

    protected override void OnNotifyMessage(Message m)
    {
        // Filtramos el mensaje WM_ERASEBKGND

        if (m.Msg != 0x14)
        {
            base.OnNotifyMessage(m);
        }
    }
}

Espero esta información les sea útil.

Hasta la próxima.

Fuentes:

http://geekswithblogs.net/cpound/archive/2006/02/27/70834.aspx

http://forums.msdn.microsoft.com/en-US/search/?q=ListView%20Flicker

2 comentarios »

  1. Hola, es justamente lo que ando buscando, que el ListView no parpadee, pero mi problema es diferente, ya que estoy actualizando completamente el control cada segundo y me sigue presentando el error.

    Lo que trato de hacer es algo así como el administrador de tareas la pestaña de procesos, cada segundo se actualiza, pero no siempre hay cambios.

    Saludos cordiales

    Paúl Somarriba

    Comentarios por piyey — diciembre 29, 2008 @ 6:18 pm

  2. Buenas que tal? no se muy bien como lo estas haciendo pero si eliminas el contenido del listview y lo volves a cargar puede ser que se presente igual el error…

    Yo intentaria acceder a los items del listview por key y modificar el valor…
    Cualquier cosa escribinos y vemos mejor tu problema.

    Saludos!!

    Comentarios por pabloide86 — diciembre 31, 2008 @ 8:33 pm


RSS feed for comments on this post. TrackBack URI

Deja un comentario

Blog de WordPress.com.