c pound

I reject your reality and substitute my own!
posts - 46, comments - 46, trackbacks - 40

My Links

News

Archives

Image Galleries

Blog Communities

Blog is a stupid word

Lunch Hour

Resources

ListView Flicker

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);
        }
    }
}

  • Share This Post:
  • Share on Twitter
  • Share on Facebook
  • Share on Technorati

Print | posted on Monday, February 27, 2006 7:44 AM |

Feedback

Gravatar

# re: ListView Flicker

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?
5/21/2006 9:31 AM | Jimmy
Gravatar

# re: ListView Flicker

I've put a sample app at the above URI if you had time to compare with what you did...
5/21/2006 9:53 AM | Jimmy
Gravatar

# re: ListView Flicker

Hmm - the URI was associated with my name -- not the most obvious thing. The URI is: www.dgp.toronto.edu/~jtalbot/flickeringListview/FlickeringListviewDoubleBuffer.zip
5/21/2006 9:54 AM | Jimmy
Gravatar

# re: ListView Flicker

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
8/14/2006 7:26 AM | Matt Godbolt
Gravatar

# re: ListView Flicker

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.
8/14/2006 8:35 AM | Dan Koster
Gravatar

# re: ListView Flicker

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! :)
8/14/2006 9:33 PM | Matt Godbolt
Gravatar

# re: ListView Flicker

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).
8/15/2006 5:47 AM | Dan Koster
Gravatar

# re: ListView Flicker

I found this useful too..
10/3/2006 11:54 PM | Gary McAllister
Gravatar

# re: ListView Flicker

Works for me too under .net 2 VS 2005. Thanks.
11/4/2006 11:23 AM | James Moore
Gravatar

# re: ListView Flicker

Worked for me as well.

Thanks alot !
1/2/2007 8:30 AM | Happy joy joy
Gravatar

# re: ListView Flicker

Worked well for me too. Just out of curiosity, why does the constructor not call the base constructor?
1/23/2007 5:38 AM | James Wansley
Gravatar

# re: ListView Flicker

I have been trying to get a Flicker-Free Listview for a while, this works great!!

Thank you very much.
2/19/2007 8:03 AM | Jeff Russo
Gravatar

# re: ListView Flicker

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,
3/30/2007 12:40 PM | James Wansley
Gravatar

# re: ListView Flicker

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. ;)
3/30/2007 1:02 PM | Dan Koster
Gravatar

# re: ListView Flicker

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.
3/30/2007 1:49 PM | Dan Koster
Gravatar

# re: ListView Flicker

anyone able to convert and apply this to visual basic .net?
5/29/2007 7:23 PM | joe
Gravatar

# re: ListView Flicker

This works also fine in VB.NET. Thanks a million because it helped me alot!!!!

9/30/2007 8:23 AM | Karl
Gravatar

# re: ListView Flicker

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;
}
}
11/17/2007 2:03 PM | Glen
Gravatar

# re: ListView Flicker

Freaking Awesome. Works Great.
I've been looking for this for two days. Whoo-hoo.
2/13/2008 2:59 PM | jcam
Gravatar

# re: ListView Flicker

Yes the shorter tip from Glen works great.
2/14/2008 4:28 AM | Magnus
Gravatar

# re: ListView Flicker

Work well on VS2008/NET3.5. Good job! Super Thanks.
2/14/2008 1:29 PM | Hays Pinthapataya
Gravatar

# re: ListView Flicker

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.
3/12/2008 10:53 AM | ItsME
Gravatar

# re: ListView Flicker

Work well on VS2008 .net 3.5 ! Thanks
4/23/2008 9:31 AM | sasayu1983
Gravatar

# re: ListView Flicker

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.
4/23/2008 4:17 PM | krc
Gravatar

# re: ListView Flicker

Works perfectly !!
5/4/2008 4:25 AM | MMH
Gravatar

# re: ListView Flicker

Awesome!

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

thanks for the contribution.
5/11/2008 1:23 AM | Greg
Gravatar

# re: ListView Flicker

I havent tried Dan's idea but Glens modification works very well!
Thanks
6/19/2008 2:20 AM | Sameer
Gravatar

# re: ListView Flicker

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.
7/10/2008 7:36 AM | Rick
Gravatar

# re: ListView Flicker

I've discovered that rather than overriding OnNotifyMessage, I override WndProc(ref Message m), and this solves my problem.
7/11/2008 6:40 AM | Rick
Gravatar

# re: ListView Flicker

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.
7/11/2008 7:10 AM | Dan Koster
Gravatar

# Something more, that was helpful for me :

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.
7/15/2008 8:40 PM | Mohammad Rastkar
Gravatar

# re: ListView Flicker

It's Working Fine...
7/16/2008 1:22 AM | Ramaraju
Gravatar

# Something more, that was helpful for me :

... Also I've tested suggestion in my last post, for 2000 items (adding separately) and then adjusting the listview, then it's work nice.
7/16/2008 3:13 AM | Mohammad Rastkar
Gravatar

# re: ListView Flicker

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
7/22/2008 12:31 PM | Sergey
Gravatar

# re: ListView Flicker

Works great on a virtual list. Thanks lots for making my control smoother.
8/27/2008 8:54 AM | Jesse
Gravatar

# re: ListView Flicker

Can someone post the VB.Net version of this fix?
9/14/2008 4:14 PM | Don Kuelbs
Gravatar

# re: ListView Flicker

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?
10/17/2008 8:08 AM | Richard
Gravatar

# re: ListView Flicker

Thanks to Sergey!
This works great for me adapted to VS C++! An elegant solution.
11/26/2008 11:59 AM | Alexey
Gravatar

# re: ListView Flicker

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.
2/6/2009 9:28 PM | David
Gravatar

# re: ListView Flicker

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.
2/8/2009 5:29 PM | David
Gravatar

# re: ListView Flicker

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.
2/12/2009 4:36 PM | Martin
Gravatar

# re: ListView Flicker

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.
2/15/2009 6:31 PM | David
Gravatar

# re: ListView Flicker

' 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)
2/20/2009 6:50 AM | T Borg
Gravatar

# To Don Kuelbs - asking for VB version

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
2/20/2009 7:38 AM | T Borg
Gravatar

# re: ListView Flicker

Thanks so much for this code. It works perfectly for me. I was pulling my hair out trying to fix this all morning. Thanks!
4/21/2009 11:59 AM | rbw
Gravatar

# re: ListView Flicker

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!
5/11/2009 3:54 PM | timmy
Gravatar

# re: ListView Flicker

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

works pretty fine for me
6/10/2009 7:19 AM | Knowledge Chikuse
Gravatar

# re: ListView Flicker

works like a charm for my project

thanks for the code
1/18/2010 5:26 AM | suguz
Gravatar

# re: ListView Flicker

Thank you for the code, this lines worked for me perfectly!
2/15/2010 8:12 AM | Lcb
Gravatar

# re: ListView Flicker

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
2/24/2010 8:37 AM | Martyn
Gravatar

# re: ListView Flicker

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
3/4/2010 1:34 PM | Rajesh
Gravatar

# re: ListView Flicker

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 });
}
4/2/2010 8:12 PM | Leo
Gravatar

# re: ListView Flicker

Great! Works for me perfectly! Thanks a lot ;)
4/20/2010 2:55 AM | Martin Repka
Gravatar

# re: ListView Flicker

Fantastic! This works greats. Thank you for taking the time to post this solution.
11/9/2010 8:08 AM | Stephen Smith
Gravatar

# re: ListView Flicker

Check also if you have created your main window with WS_EX_COMPOSITED - that can be the cause of the problem.
4/18/2011 4:16 AM | Gyggs
Gravatar

# re: ListView Flicker

thank you very much.
6/19/2011 8:17 PM | Hung Le
Gravatar

# re: ListView Flicker

Work like charm. Thank you!
10/5/2011 9:02 AM | Kalin
Post A Comment
Title:
Name:
Email:
Website:
Comment:
Verification:
 
 

Powered by: