Geeks With Blogs
c pound I reject your reality and substitute my own!

The ListView control has a flicker issue. The problem appears to be that the control's Update overload is improperly implemented such that it acts like a Refresh. An Update should cause the control to redraw only its invalid regions whereas a Refresh redraws the control’s entire client area. So if you were to change, say, the background color of one item in the list then only that particular item should need to be repainted. Unfortunately, the ListView control seems to be of a different opinion and wants to repaint its entire surface whenever you mess with a single item… even if the item is not currently being displayed. So, anyways, you can easily suppress the flicker by rolling your own as follows:

class ListViewNF : System.Windows.Forms.ListView
{
    public ListViewNF()
    {
        //Activate double buffering
        this.SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.AllPaintingInWmPaint, true);

        //Enable the OnNotifyMessage event so we get a chance to filter out 
        // Windows messages before they get to the form's WndProc
        this.SetStyle(ControlStyles.EnableNotifyMessage, true);
    }

    protected override void OnNotifyMessage(Message m)
    {
        //Filter out the WM_ERASEBKGND message
        if(m.Msg != 0x14)
        {
            base.OnNotifyMessage(m);
        }
    }
}

Posted on Monday, February 27, 2006 7:44 AM | Back to top


Comments on this post: ListView Flicker

# re: ListView Flicker
Requesting Gravatar...
This didn't seem to work at all for me. It made no difference whatsoever. I'm not using .net 2, so I had to use ControlStyles.DoubleBuffer instead of ControlStyles.OptimizedDoubleBuffer - would that make difference or not?
Left by Jimmy on May 21, 2006 9:31 AM

# re: ListView Flicker
Requesting Gravatar...
I've put a sample app at the above URI if you had time to compare with what you did...
Left by Jimmy on May 21, 2006 9:53 AM

# re: ListView Flicker
Requesting Gravatar...
Hmm - the URI was associated with my name -- not the most obvious thing. The URI is: www.dgp.toronto.edu/~jtalbot/flickeringListview/FlickeringListviewDoubleBuffer.zip
Left by Jimmy on May 21, 2006 9:54 AM

# re: ListView Flicker
Requesting Gravatar...
Hi Dan,
Thanks for the post. I'm using version 2, and despite what MSDN says, if I use the UserPaint option then nothing appears in the listview. If I handle the OnPaint() and pass it along to the underlying listview control it still doesn't draw anything...any tips?

Everything's working, but I'm wary of relying on fringe behaviour like this (ie setting OptimizedDoubleBuffer and NOT UserPaint).

Thanks,

Matt
Left by Matt Godbolt on Aug 14, 2006 7:26 AM

# re: ListView Flicker
Requesting Gravatar...
Heya Matt,

UserPaint tells the control to not render anything because you’re going to draw your own custom ListView UI. That’s why nothing shows up when you set UserPaint to True. It’s blank because anything it draws would probably interfere with anything you might draw. What’s probably happening behind the scenes is a simple if(!UserPaint) in the ListView’s Paint function.

I can’t be sure what’s going wrong with your code without more details. But, I can tell you that the code above was actually working mere moments before I copy & pasted it. As far as fringe behavior… remember that this was a hack to work around a flaw in the framework.
Left by Dan Koster on Aug 14, 2006 8:35 AM

# re: ListView Flicker
Requesting Gravatar...
Thanks Dan - my code's a 100% copy and paste of your original code, and it's working fine. I'm just saying that if I OR in the ControlStyles.UserPaint flag as MSDN suggests I need to, then obviously I'm supposed to redraw the control myself. However, I don't really want to; I just want default drawing behaviour without flickering!

As it seems to be working without the UserPaint flag set (despite MSDN telling me it needs to be set) I think I'm going to leave it and keep my fingers crossed!

Thanks for the reply, and for the original post which has saved me from throwing my monitor out the window in frustration! :)
Left by Matt Godbolt on Aug 14, 2006 9:33 PM

# re: ListView Flicker
Requesting Gravatar...
NP, Matt! I'm glad to see someone found something useful on my blog. I guess I should start updating it again.

You're pretty safe to keep using whatever you can get to work. Microsoft is really good about not making changes at a later date that would break stuff that's working *right now* (even if what you've got working was a hack).
Left by Dan Koster on Aug 15, 2006 5:47 AM

# re: ListView Flicker
Requesting Gravatar...
I found this useful too..
Left by Gary McAllister on Oct 03, 2006 11:54 PM

# re: ListView Flicker
Requesting Gravatar...
Works for me too under .net 2 VS 2005. Thanks.
Left by James Moore on Nov 04, 2006 11:23 AM

# re: ListView Flicker
Requesting Gravatar...
Worked for me as well.

Thanks alot !
Left by Happy joy joy on Jan 02, 2007 8:30 AM

# re: ListView Flicker
Requesting Gravatar...
Worked well for me too. Just out of curiosity, why does the constructor not call the base constructor?
Left by James Wansley on Jan 23, 2007 5:38 AM

# re: ListView Flicker
Requesting Gravatar...
I have been trying to get a Flicker-Free Listview for a while, this works great!!

Thank you very much.
Left by Jeff Russo on Feb 19, 2007 8:03 AM

# re: ListView Flicker
Requesting Gravatar...
Here is a new development. Adding an item to position 0 in the listview still causes a non-buffered redraw of the entire list of items. Is there a way around this?

Thanks,
Left by James Wansley on Mar 30, 2007 12:40 PM

# re: ListView Flicker
Requesting Gravatar...
It would, wouldn't it. If you insert an item at position 0 then every following item will have to move down one row to make room. If you added an item at position 3 then items 4 through ListView.Items.Count - 1 would all shift down by one and have to be repainted.

Trust me. You don't want to "fix" this behavior. ;)
Left by Dan Koster on Mar 30, 2007 1:02 PM

# re: ListView Flicker
Requesting Gravatar...
On second thought, you’re probably talking about adding a new item at position 0 when that particular position is not actually being displayed. Why should it repaint the list if your view of the list is from, say, item 10 to item 20? Well, your view is based on index numbers not on actual items. So your view of the list is still from item 10 to item 20 except that now (after adding a new item 0) that view is of a slightly different set of items. Thus, they get repainted. You should be able to follow these steps to get around this and keep the same items in view after you have added one above:

1) call ListView.BeginUpdate()to suspend painting of the list
2) add your item(s)
3) call ListViewItem.EnsureVisible() on the item you wish to appear last in your view of the list (because this one will have been pushed off the bottom of the list by adding one above)
4) call ListViewItem.EnsureVisible() on the item you wish to be at the top of your view (otherwise the top item might only be partially in view)
5) call ListView.EndUpdate() to resume painting of the list

Of course, if the call to EndUpdate causes the list to paint then this whole exercise is useless. I haven’t tested it, so let me know if it doesn’t work.
Left by Dan Koster on Mar 30, 2007 1:49 PM

# re: ListView Flicker
Requesting Gravatar...
anyone able to convert and apply this to visual basic .net?
Left by joe on May 29, 2007 7:23 PM

# re: ListView Flicker
Requesting Gravatar...
This works also fine in VB.NET. Thanks a million because it helped me alot!!!!

Left by Karl on Sep 30, 2007 8:23 AM

# re: ListView Flicker
Requesting Gravatar...
You can also just set this.DoubleBuffer = true in the constructor. I've used this in several projects and seems to work rather well too.

public class FlickerFreeListView : ListView
{
public FlickerFreeListView()
{
this.DoubleBuffered = true;
}
}
Left by Glen on Nov 17, 2007 2:03 PM

# re: ListView Flicker
Requesting Gravatar...
Freaking Awesome. Works Great.
I've been looking for this for two days. Whoo-hoo.
Left by jcam on Feb 13, 2008 2:59 PM

# re: ListView Flicker
Requesting Gravatar...
Yes the shorter tip from Glen works great.
Left by Magnus on Feb 14, 2008 4:28 AM

# re: ListView Flicker
Requesting Gravatar...
Work well on VS2008/NET3.5. Good job! Super Thanks.
Left by Hays Pinthapataya on Feb 14, 2008 1:29 PM

# re: ListView Flicker
Requesting Gravatar...
Great...It works good in .net 2.0..How come you know about all these stuff...Please guide me in learning all these tricks..

Thanks..It saved a lot of time and works like a gem.
Left by ItsME on Mar 12, 2008 10:53 AM

# re: ListView Flicker
Requesting Gravatar...
Work well on VS2008 .net 3.5 ! Thanks
Left by sasayu1983 on Apr 23, 2008 9:31 AM

# re: ListView Flicker
Requesting Gravatar...
Awesome!

It works like a charm. I have a monitor application that displays log messages at runtime. The listview flickering made th application look aweful. With this fix, the application looks great!!!

Thanks a lot.
Left by krc on Apr 23, 2008 4:17 PM

# re: ListView Flicker
Requesting Gravatar...
Works perfectly !!
Left by MMH on May 04, 2008 4:25 AM

# re: ListView Flicker
Requesting Gravatar...
Awesome!

I'm using it with 3.5 Framework on a 64bit os and it works fine as well.

thanks for the contribution.
Left by Greg on May 11, 2008 1:23 AM

# re: ListView Flicker
Requesting Gravatar...
I havent tried Dan's idea but Glens modification works very well!
Thanks
Left by Sameer on Jun 19, 2008 2:20 AM

# re: ListView Flicker
Requesting Gravatar...
I'm using a ListBox (not a ListView) and unfortunately, even extending the ListBox class in the exact same manner, I'm still seeing flicker whenever items are drawn. Does this approach only work with ListViews?

UPDATE -- I just compiled, ran your example program, and it flickers very badly. I'm using .Net 2.0. I also had to add a call to Invoke in your sample code because you were making modifications to the UI on a non-UI thread.
Left by Rick on Jul 10, 2008 7:36 AM

# re: ListView Flicker
Requesting Gravatar...
I've discovered that rather than overriding OnNotifyMessage, I override WndProc(ref Message m), and this solves my problem.
Left by Rick on Jul 11, 2008 6:40 AM

# re: ListView Flicker
Requesting Gravatar...
This approach, via OnNotifyMessage or WndProc, can be used to filter out the WM_ERASEBKGND message in a derived control of any type. I know it alleviates the flicker problem with the ListView control, but I haven't had need to try it with the ListBox. It should have the a similar effect on all list controls. A simpler solution might be to just try setting the ListBox's DoubleBuffered property to true.

Where did you need to add in a call to Invoke? Nothing in the sample code should need it... and indeed it seems to work as is for myself and everyone else.
Left by Dan Koster on Jul 11, 2008 7:10 AM

# Something more, that was helpful for me :
Requesting Gravatar...
With 'DoubleBuffered' true for your derived listview and the form that contains your listview, you can do onething more to really have smooth update of listview (maybe it's not suitable for some situations, like when you update listview with huge amount of data) :

Just before updating, hide the listview :

ListViewEx_control.Visible = false;

after that, show it again.
Left by Mohammad Rastkar on Jul 15, 2008 8:40 PM

# re: ListView Flicker
Requesting Gravatar...
It's Working Fine...
Left by Ramaraju on Jul 16, 2008 1:22 AM

# Something more, that was helpful for me :
Requesting Gravatar...
... Also I've tested suggestion in my last post, for 2000 items (adding separately) and then adjusting the listview, then it's work nice.
Left by Mohammad Rastkar on Jul 16, 2008 3:13 AM

# re: ListView Flicker
Requesting Gravatar...
You can always get around the protected aspect of Control.SetStyle with reflection. This means you don't need an extra derived type at all:

public class StyleHelper
{
public static void DisableFlicker(System.Windows.Forms.Control ctrl)
{
MethodInfo method = ctrl.GetType().GetMethod("SetStyle", BindingFlags.Instance | BindingFlags.NonPublic);
if (method != null)
{
method.Invoke(ctrl, new object[] { ControlStyles.OptimizedDoubleBuffer | ControlStyles.AllPaintingInWmPaint, true });
}
}
}

Then just call StyleHelper.DisableFlicker(myList); and there you are.

-S
Left by Sergey on Jul 22, 2008 12:31 PM

# re: ListView Flicker
Requesting Gravatar...
Works great on a virtual list. Thanks lots for making my control smoother.
Left by Jesse on Aug 27, 2008 8:54 AM

# re: ListView Flicker
Requesting Gravatar...
Can someone post the VB.Net version of this fix?
Left by Don Kuelbs on Sep 14, 2008 4:14 PM

# re: ListView Flicker
Requesting Gravatar...
With any of the solutions on here, f you EnsureVisible on each item added, think AutoScroll, and have an item selected further up, the list view goes bonkers trying to scroll between the bottom and the selected item.

Any ideas why?
Left by Richard on Oct 17, 2008 8:08 AM

# re: ListView Flicker
Requesting Gravatar...
Thanks to Sergey!
This works great for me adapted to VS C++! An elegant solution.
Left by Alexey on Nov 26, 2008 11:59 AM

# re: ListView Flicker
Requesting Gravatar...
This certainly got rid of flicker but it also changed the appearance of the font. Also as I move the mouse pointer across rows the text changes subtlety from what appears to be almost a bold font to a non-bold font. I did not make the font bold and it really doesn't appear bold but it definitely changes appearance.
Left by David on Feb 06, 2009 9:28 PM

# re: ListView Flicker
Requesting Gravatar...
Another interesting observation. The text in the last column (rightmost) appears as it should. I used the Windows magnifier and I can see that what I thought was semi-bolded text is really blurry text. Quite strange.
Left by David on Feb 08, 2009 5:29 PM

# re: ListView Flicker
Requesting Gravatar...
Thank you (and google :-)

I use this line (c# 3.0) to set the protected Property "DoubleBuffered":

myListView.GetType().GetProperty("DoubleBuffered", BindingFlags.NonPublic | BindingFlags.Instance).SetValue(myListView, true, null);


... and it works great.
Left by Martin on Feb 12, 2009 4:36 PM

# re: ListView Flicker
Requesting Gravatar...
Anyone have any idea why I'm seeing this effect? Here is the link to see the screen grab; http://i18.photobucket.com/albums/b133/TxDot/Font%20Issue/FontProblemWithDoubleBufferingSmall.jpg

Notice the difference between the text in the I/O Reads column and the text in the I/O Writes column. If I turn off the double buffering it goes away and the text in both columns looks like the text in the I/O Writes column.
Left by David on Feb 15, 2009 6:31 PM

# re: ListView Flicker
Requesting Gravatar...
' test to set some properties on the treeview '
Dim m As MethodInfo = t.GetType.GetMethod("SetStyle", BindingFlags.Instance Or BindingFlags.NonPublic)
Dim o() As Object = {ControlStyles.OptimizedDoubleBuffer Or ControlStyles.AllPaintingInWmPaint, True}
m.Invoke(t, o)
Left by T Borg on Feb 20, 2009 6:50 AM

# To Don Kuelbs - asking for VB version
Requesting Gravatar...
Dim t As ListView = lstbox
t.GetType.GetProperty("DoubleBuffered", BindingFlags.Instance Or BindingFlags.NonPublic).SetValue(t, True, Nothing)

Works like a dance...I have spent days searchinng for a solution for this flickering (i have to update the list every 100 ms...

Thanks PM Martin and all you guys!
ListView Flicker 2/12/2009 4:36 PM Martin
Left by T Borg on Feb 20, 2009 7:38 AM

# re: ListView Flicker
Requesting Gravatar...
Thanks so much for this code. It works perfectly for me. I was pulling my hair out trying to fix this all morning. Thanks!
Left by rbw on Apr 21, 2009 11:59 AM

# re: ListView Flicker
Requesting Gravatar...
At first, this didn't work at all for me when I added it into my project. I tried several variations, but it still flickered. Then I tried it on a fresh (new) project, and it worked perfectly! Finally, I was able to isolate why it wasn't working on my old project.

The old project did not call Application.EnableVisualStyles() in the main() function. Without this line, you still get the flickering. Adding this line to my old project made everything work perfectly!
Left by timmy on May 11, 2009 3:54 PM

# re: ListView Flicker
Requesting Gravatar...
listView.GetType().GetProperty("DoubleBuffered", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance).SetValue(listView, true, null);

works pretty fine for me
Left by Knowledge Chikuse on Jun 10, 2009 7:19 AM

# re: ListView Flicker
Requesting Gravatar...
works like a charm for my project

thanks for the code
Left by suguz on Jan 18, 2010 5:26 AM

# re: ListView Flicker
Requesting Gravatar...
Thank you for the code, this lines worked for me perfectly!
Left by Lcb on Feb 15, 2010 8:12 AM

# re: ListView Flicker
Requesting Gravatar...
Hi all,

I have a listview which holds the information of visitors to our building, i want to refresh the data every 2 seconds as several users will be using the system. How are people refreshing their data as well as maintaining the scroll position?

Thanks
Left by Martyn on Feb 24, 2010 8:37 AM

# re: ListView Flicker
Requesting Gravatar...
Hi,

How do i call the function from ListViewNF class? I have copied the whole class into my source code?

I would appreciate if somebody could assist me with this.

Thanks
Left by Rajesh on Mar 04, 2010 1:34 PM

# re: ListView Flicker
Requesting Gravatar...
This one it works fine for me:

private void SetDoubleBuffered(Control control)
{
typeof(Control).InvokeMember("DoubleBuffered", BindingFlags.SetProperty | BindingFlags.Instance | BindingFlags.NonPublic, null, control, new object[] { true });
}
Left by Leo on Apr 02, 2010 8:12 PM

# re: ListView Flicker
Requesting Gravatar...
Great! Works for me perfectly! Thanks a lot ;)
Left by Martin Repka on Apr 20, 2010 2:55 AM

# re: ListView Flicker
Requesting Gravatar...
Fantastic! This works greats. Thank you for taking the time to post this solution.
Left by Stephen Smith on Nov 09, 2010 8:08 AM

# re: ListView Flicker
Requesting Gravatar...
Check also if you have created your main window with WS_EX_COMPOSITED - that can be the cause of the problem.
Left by Gyggs on Apr 18, 2011 4:16 AM

# re: ListView Flicker
Requesting Gravatar...
thank you very much.
Left by Hung Le on Jun 19, 2011 8:17 PM

# re: ListView Flicker
Requesting Gravatar...
Work like charm. Thank you!
Left by Kalin on Oct 05, 2011 9:02 AM

# re: ListView Flicker
Requesting Gravatar...
Thanks for this flicker-free ListView, now I've got no more annoying flicker! :D
Left by Nando on Aug 15, 2012 9:50 AM

Your comment:
 (will show your gravatar)


Copyright © Dan Koster | Powered by: GeeksWithBlogs.net