Click here to Skip to main content
15,868,340 members
Articles / Programming Languages / C#
Article

Flicker-free ListView in .NET and XP

Rate me:
Please Sign up or sign in to vote.
4.88/5 (27 votes)
26 Jan 20036 min read 352.7K   4.5K   73   64
This article discusses the problems with the .NET ListView and offers a solution to fix those problems.

Sample Image - ListViewXP.gif

Introduction

The focus of this article is to extend and improve the .NET ListView control. The current ListView control is very useful, but has a nasty flicker problem associated with it. My goal is to eliminate or significantly reduce this flicker. The solution provided in this article only works with Windows XP with an associated manifest file. This is the first of three articles I am writing to improve the ListView control. The others will not require XP. In addition, other things I will discuss in this article do not require XP.

It flickers

There are two situations in which you will encounter flickering.

  • Dynamically adding items

    If you attempt to add multiple items while using an ImageList with multiple icons (in a for or foreach loop), and you would like these items to display as they are being added, you need to use Refresh() or Update() (you can use others like Application.DoEvents()). Any of the above mentioned will cause an annoying flicker. To avoid the flicker, you do not place Refresh(), Update() etc inside the for loop. This will cause the ListView to be blank until all of the items are added. At times, this is the best way to go, but if doing this requires a significant amount of time, it is not a good idea as the user will think the program has locked up.

  • Resizing the main form with a ListView docked

    When a ListView is Docked, as in Windows Explorer (and you have a good amount of items), resizing the main form will cause all of the items to flicker.

Update: I originally had three. Third one being updating/changing an item, but you just need to use Update() rather than Refresh() to fix this.

Why does it flicker?

When you add a new item to the ListView, the control invalidates itself. This causes the background to be erased, and all items to be redrawn again. It should only invalidate the bounds of the new item, causing only the item to be drawn, but it doesn't. This means that calling Refresh() and Update() will have the same effect, where you would expect Update() to only update the new or changed items. In my next article, I will discuss a couple of techniques to allow only the newly added item to be redrawn.

Another reason it flickers is because it is not truly double-buffered. You can extend the ListView class, and add

C#
SetStyle(ControlStyles.DoubleBuffer,
true)
, but it has no effect. The technique described here shows you how to double buffer the ListView.

DoubleBuffering the ListView

If you are familiar with programming the ListView (or CListCtrl) using only the Win32 API, or MFC, you will notice that you can set particular styles for the ListView. Most of these styles are already set in the .NET ListView, and are customizable (for example, the ViewModes, how icons will be aligned.. will they be auto-arranged, etc).

There are also "Extended" Styles for the ListView. These styles add a few extras such as using One-Click activate with hot-tracking (similar to Windows 98 Explorer in web-mode, where clicking the item once will launch the item, "entering" the item will cause it to be selected" etc..) There is also an extended style to allow gridlines to be drawn around items in Details/Report mode (This is already implemented in .NET, when you choose details view and show gridlines).

In Windows XP, there is an extended-style called LVS_EX_DOUBLEBUFFER. This is what we want. Unfortunately it is only available for Common Controls version 6, which means we need Windows XP as well as a manifest file (or embedded resource). Additionally there is a style called LVS_EX_BORDERSELECT which tells the ListView (in Large Icon mode) to highlight the border of the icon rather than to paint over it (This is available with Common Controls version 4.71, so this will work without XP).

So now our goal is to actually make use of these extended styles. This is pretty easy to do if you're familiar with the SendMessage Windows function. We import this function from user32.dll, and use it to retrieve and set extended styles. Here's the code:

C#
public void SetExStyles()
{
    LVS_EX styles = (LVS_EX)SendMessage(this.Handle, 
        (int) LVM.LVM_GETEXTENDEDLISTVIEWSTYLE, 0,0);
    styles |= LVS_EX.LVS_EX_DOUBLEBUFFER | LVS_EX.LVS_EX_BORDERSELECT;
    SendMessage(this.Handle, 
        (int) LVM.LVM_SETEXTENDEDLISTVIEWSTYLE, 0, (int) styles);
}

We start by retrieving any existing Extended Styles. We then add

C#
DOUBLEBUFFER
and BORDERSELECT, and use SendMessage to add these extra styles to the current ListView. This method should be called AFTER the ListView's handle has been created. If not, it will not work as the Handle has not been defined yet. In other words, do not make a call to this in your main Form's constructor.. it should happen after the entire form has loaded.

NOTE: LVS_EX is an enumerated type of int. Each constant in here defines the proper

C#
ExtendedStyle
.
C#
LVM
is also an enumerated type representing ListView messages.

Once you've made a call to this method, you can make a loop similar to this to add items to this ListView:

C#
for (int i=0; i < 500; i++)
{
   listviewXp.Items.Add("item name", iconIndex);
   listviewXp.Update();
}

Now you will be able to see the items as they are being drawn, and you will no longer get the nasty flicker. In addition, if your ListView is docked, you can resize your form without the flicker problem. You can also call listview.Refresh() or listview.Update() after you have made a change to an existing item and the change will be made without flicker.

Running and using the sample

  • Using the sample demo

    Be sure you are using Windows XP and have both the exe and manifest file in the same directory. Run it, and press the button to watch the items appear without flicker. If you are not using XP, you will still see flicker, but you will be able to see the BorderSelect mode.

  • Compiling the sample app

    Open up Visual Studio .NET and compile it. Before you run it, copy the manifest file to the Debug or Release directory where the exe is.

  • Using ListViewXP in your own app

    Just copy the ListViewXP.cs file and add it to your app. Note that if you want the double buffering effect, you must provide the manifest file. You can copy the one I provided and rename it to YourAppName.exe.manifest. You may use and distribute this class freely, but if you do so, please include a comment that includes my name and a link to this article. Also, if you do use it, please let me know how it worked for you.

Conclusion

Using the SendMessage function from user32.dll allows us to extend the .NET ListView, so we can add DoubleBuffering support in XP to eliminate flicker. Additionally, we can use this function to add other extended ListView styles, and this technique can be applied to other controls as well. Hope you enjoyed the article.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Web Developer
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
QuestionCan a license be added? Pin
Member 1229581627-Sep-16 8:56
Member 1229581627-Sep-16 8:56 
GeneralNice application Pin
ramesh bs11-Sep-09 0:03
ramesh bs11-Sep-09 0:03 
QuestionMulitline TextBox Control Flickering Problem in C# Pin
bishnupatro12-Feb-08 19:22
bishnupatro12-Feb-08 19:22 
Hi,

In my C# application there is a multiline textbox with vertical scrollbar. When the multiline textbox get updated with new data, the vertical scrollbar flickers (from top to bottom) with each update on the textbox. How can I prevent the scrollbar flickering when the multiline textbox get updated each time.

Thanking you in advance.

Bishnu
GeneralAn easier way Pin
cptHotKeys15-Oct-07 10:39
cptHotKeys15-Oct-07 10:39 
GeneralRe: An easier way Pin
Elliot Knight5-Nov-07 6:08
Elliot Knight5-Nov-07 6:08 
GeneralRe: An easier way Pin
cptHotKeys5-Nov-07 9:21
cptHotKeys5-Nov-07 9:21 
QuestionAnyone know how to get this to work in VB6? Pin
jjohnston14-Jul-07 7:39
jjohnston14-Jul-07 7:39 
Answer[Message Removed] Pin
immetoz4-Oct-08 2:05
immetoz4-Oct-08 2:05 
QuestionWill it work only if we create a separate user control and then apply the style? Pin
Dumb Programmer13-Jun-07 0:08
Dumb Programmer13-Jun-07 0:08 
GeneralAdditional fix Pin
niemkhuccuoi07013-Jun-07 18:18
niemkhuccuoi07013-Jun-07 18:18 
QuestionSimpler solution...? Pin
pat6644222-May-06 11:29
pat6644222-May-06 11:29 
AnswerRe: Simpler solution...? Pin
Giovanni Montrone14-May-06 9:41
Giovanni Montrone14-May-06 9:41 
AnswerBEST SOLUTION! Pin
djyakov24-May-06 8:47
djyakov24-May-06 8:47 
AnswerRe: Simpler solution...? Pin
AutonomousOne4-Jul-06 4:08
AutonomousOne4-Jul-06 4:08 
GeneralRe: Simpler solution...? Pin
banduraj31-Jul-06 7:29
banduraj31-Jul-06 7:29 
GeneralRe: Simpler solution...? Pin
holyfoek1-Nov-06 10:44
holyfoek1-Nov-06 10:44 
GeneralRe: Simpler solution...? Pin
esskar22-Oct-07 23:33
esskar22-Oct-07 23:33 
GeneralRe: Simpler solution...? Pin
Gabriel Szabo25-Apr-08 4:12
Gabriel Szabo25-Apr-08 4:12 
GeneralRe: Simpler solution...? Pin
vigylant29-Oct-08 9:48
vigylant29-Oct-08 9:48 
GeneralRe: Simpler solution...? Pin
Philip Leitch23-Nov-08 19:19
Philip Leitch23-Nov-08 19:19 
GeneralRe: Simpler solution...? Pin
dmex27-Dec-08 19:20
dmex27-Dec-08 19:20 
GeneralRe: Simpler solution...? Pin
openshac20-Jan-09 23:50
openshac20-Jan-09 23:50 
GeneralRe: Simpler solution...? Pin
yetibrain15-Jun-09 14:36
yetibrain15-Jun-09 14:36 
QuestionRe: Simpler solution...? : Not working in Windows 7 !!! Pin
samprog27-Aug-10 1:10
samprog27-Aug-10 1:10 
AnswerRe: Simpler solution...? : Not working in Windows 7 !!! Pin
esskar27-Aug-10 1:14
esskar27-Aug-10 1:14 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.