Die Listview und das Flackern


Thomas Wölfer
Thomas Wölfer

11. November 2004


Wer in einem Windows.Forms Programm die ListView Klasse einsetzt und oft die Elemente in der ListView erneuert, der wird wissen das die ListView zu einem nervigen flackern neigt. Jedes Update der View führt zu einem Repaint, und das macht die Sache reichlich unruhig.

Programme die für XP oder neuere Windows-Versionen gedacht sind können das aber leicht abstellen. Für ein .Net Programm braucht man dazu eine Manifest-Datei und den folgenden Interop-Code. Hintergrund: Die 'neueren' Versionen der ListView aus den Common-Controls können Double-Buffering verwenden - das muss man aber eben anwerfen. (Erst dann, wenn das Handle für die ListView erzeugt wurde.) Der folgende Code muss also einfach in die eigene Klasse kopiert werden, dann legt man das Manifest-File an um die neueste CommonControl-DLL zu verwenden, und nach der erzeugen des ListView-Handles ruft man dann SetDoubleBuffered() auf.

[ComVisibleAttribute(false)]
[SuppressUnmanagedCodeSecurityAttribute()]
internal class NativeMethods
{
  [DllImport("user32.dll")]
 
public static extern int SendMessage( IntPtr hWnd, int msg, int wParam, IntPtr lParam );
}

private const int LVM_FIRST = 0x1000;
private const int LVM_SETEXTENDEDLISTVIEWSTYLE = (LVM_FIRST + 54);
private const int LVM_GETEXTENDEDLISTVIEWSTYLE = (LVM_FIRST + 55);
private const int LVS_EX_DOUBLEBUFFER = 0x00010000;

public void MakeDoubleBuffered()
{
  int styles = (int)NativeMethods.SendMessage( this.Handle, (int)LVM_GETEXTENDEDLISTVIEWSTYLE, 0, (IntPtr)0);

  styles |= LVS_EX_DOUBLEBUFFER;

  NativeMethods.SendMessage(this.Handle, (int)LVM_SETEXTENDEDLISTVIEWSTYLE, 0, (IntPtr)styles);
}