Winforms ListView Flickering

First of all, let me start by saying I love WPF! :- ) I do Winforms when I really must. It reminds me of my MFC days and all the Win32 tricks and compatibility issues. Good old days are well behind now. Luckily, new technologies like WPF are making those issues just remnants of the past.

If you do Winforms development and especially work with ListView control, you may experience flickering. This is most notable when adding many items in succession.

To rectify this fortunately there is a very easy way. It involves a simple SendMessage to the ListView control. This is of course possible because in Winforms, a ListView control is just a wrapper around Win32 list view control. Unfortunately, even in NET4 Winforms there are no properties exposed that would make this job absolutely trivial. Instead, one must revert to P/Invoke trickery.

ListView maintains a few “extended” list view styles which are unrelated to WS_EX standard Win32 extended styles. These special extended styles are accessed by sending LVM_SETEXTENDEDLISTVIEWSTYLE / LVM_GETEXTENDEDLISTVIEWSTYLE to set / get the current value.

So, to disable ListView flickering we need to get the current “extended” style, add LVS_EX_DOUBLEBUFFER and set it back. See the image above for the effect as seen in Windows Explorer. If you want your ListView to look even more fancy, you may experiment by adding LVS_EX_BORDERSELECT too.

    public static class ListViewHelper
    {
        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 = 0x10000;
        private const int LVS_EX_BORDERSELECT = 0x8000;

        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam);

        public static void SetPrettyStyle(this ListView listView)
        {
            var oldStyles = (int) SendMessage(listView.Handle, LVM_GETEXTENDEDLISTVIEWSTYLE, (IntPtr) 0, (IntPtr) 0);
            SendMessage(listView.Handle, LVM_SETEXTENDEDLISTVIEWSTYLE, (IntPtr) 0, (IntPtr) (oldStyles | LVS_EX_DOUBLEBUFFER));
        }
    }

As this is implemented as extension method, all you need to do now is make call like this:

    public void MyMethod()
    {
        _myListView.SetPrettyStyle();
    }

Tags: , , ,

Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>