.NET Forum / Windows Forms / WinForm Controls / December 2007
.NET FW v1.1 Listview flickering issue
|
|
Thread rating:  |
Richard - 16 Nov 2007 14:33 GMT Hello community,
I need a way to reduce flickering of the listview in .NET FW v1.1.
The case: I have a listview control hosted in a plain form that has 20 rows and 5 columns. The data for a few of these rows changes often, about 2 times per second. The effect: the listview flickers each row where the data has been updated. If a window partial covers the listview, then the entire listview flickers, regardless whether any data within it has changed.
I have tried several combinations of DoubleBuffer, UserPaint, AllPaintingInWmPaint, WM_SETREDRAW, LockWindowUpdate, etc... even tried doing a side-by-side of the listview between 1.1 and 2.0 (fails due to imcompatibility of CLR), ... and nothing seems to help.
In .NET 2.0, All is fine once I apply the OptimizedDoubleBuffer.
Any way to do this? What can be done to achieve the same effects of the OptmizedDoubleBuffer in .NET 2.0, but in .NET FW v1.1?
Thank you,
Linda Liu[MSFT] - 19 Nov 2007 07:47 GMT Hi Richard,
The ListView in .NET 1.x doesn't support double buffering. So it's no use setting the DoubleBuffer style to true for the ListView in .NET 1.x.
In fact, the reason why the ListView flickers when it is updated frequently is that the WM_ERASEBKGND message is sent to the ListView every time the ListView needs redrawing. Thus, the ListView items are erased with the back color first and then redraw the text in them.
To reduce the flickering, we can intercepting the WM_ERASEBKGND message in the WndProc method of a ListView derived class and clip all the bounds of the ListView items out of the drawing region, so that the bounds of the ListView items will not erased with back color and the flickering disappears.
The following is a sample code:
using System.Windows.Forms; using System.Drawing;
public class MyListView:ListView { int WM_ERASEBKGND=0x14; protected override void WndProc(ref Message m) { if(m.Msg == WM_ERASEBKGND) { Color backColor = Enabled ? BackColor : Color.FromKnownColor(KnownColor.Control); // create a graphics object using the supplied handle to the device context. Graphics graphics = Graphics.FromHdc(m.WParam); // clip all of the list view items out of the drawing region foreach (ListViewItem item in Items) { graphics.ExcludeClip(new Rectangle(item.Bounds.Left + 2,item.Bounds.Top,item.Bounds.Width-2,item.Bounds.Height)); } // now paint what's left with the background color using(SolidBrush brush = new SolidBrush(backColor)) { graphics.FillRegion(brush, graphics.Clip); graphics.Dispose(); } } else { base.WndProc (ref m); } } }
The above code works well on my side. Please try it in your project to see if it could solve the problem and let me know the result.
Sincerely, Linda Liu Microsoft Online Community Support
================================================== Get notification to my posts through email? Please refer to http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif ications. Note: The MSDN Managed Newsgroup support offering is for non-urgent issues where an initial response from the community or a Microsoft Support Engineer within 1 business day is acceptable. Please note that each follow up response may take approximately 2 business days as the support professional working with you may need further investigation to reach the most efficient resolution. The offering is not appropriate for situations that require urgent, real-time or phone-based interactions or complex project analysis and dump analysis issues. Issues of this nature are best handled working with a dedicated Microsoft Support Engineer by contacting Microsoft Customer Support Services (CSS) at http://msdn.microsoft.com/subscriptions/support/default.aspx. ================================================== This posting is provided "AS IS" with no warranties, and confers no rights.
Richard - 19 Nov 2007 15:34 GMT Hello Linda,
Works ok in a simple test program, but isn't really in our application... it still flickers; and even more if the the window is partially hidden, or when spy++ is connected.
Our listview has the grid style drawing enabled. Is there a way now to turn off or delay drawing (i.e. would WM_SETDREDRAW work here)?
Thank you,
> Hi Richard, > [quoted text clipped - 77 lines] > > This posting is provided "AS IS" with no warranties, and confers no rights. Linda Liu[MSFT] - 20 Nov 2007 10:46 GMT Hi Richard,
Thank you for your prompt reply!
Sorry that I made a mistake in my previous reply, i.e. I said the ListView in .NET 1.x doesn't support double buffering.
In fact, the ListView class in .NET Framework is a wrapper of the native ListView control and the native ListView control on Windows XP and later supports double buffering. Although the ListView in .NET 1.x doesn't provide the DoubleBuffered property, we can use Win32 API SendMessage function to set the ListView to use double buffering.
To use the native ListView control, call Application.EnableVisualStyles before you start your main message loop in the static Main method. The following is a sample:
public class Form1 : System.Windows.Forms.Form { [STAThread] static void Main() { Application.EnableVisualStyles(); Application.Run(new Form1()); } }
public class MyListView:ListView { const int LVM_FIRST=0x1000; const int LVM_SETEXTENDEDLISTVIEWSTYLE = LVM_FIRST+54; const int LVS_EX_DOUBLEBUFFER = 0x10000; [DllImport("user32.dll")] static extern int SendMessage(IntPtr hWnd, int msg, int wParam,int lParam);
public MyListView() { this.SetStyle(ControlStyles.DoubleBuffer,true); } public void SetDoubleBuffered() { SendMessage(this.Handle,LVM_SETEXTENDEDLISTVIEWSTYLE,LVS_EX_DOUBLEBUFFER,LVS _EX_DOUBLEBUFFER); } protected override void OnHandleCreated(System.EventArgs e) { base.OnHandleCreated (e); this.SetDoubleBuffered(); } }
Note that the above workaround only applies to Windows XP and later.
Please try it in your project to see if it solves the problem and let me know the result.
Sincerely, Linda Liu Microsoft Online Community Support
Richard - 20 Nov 2007 18:55 GMT Hello Linda,
Yes that did the trick. Thank you. It be nice to have this included in the documentation!
Richard
> Hi Richard, > [quoted text clipped - 57 lines] > Linda Liu > Microsoft Online Community Support Linda Liu[MSFT] - 21 Nov 2007 04:15 GMT Hi Richard,
Thank you for your feedback and I am glad to hear that the problem is fixed.
I will make a suggestion to our documentation team about including this tip in the documentation.
Thank you for reminding and support for Microsoft!
If you have any other questions in the future, please don't hesitate to contact us. It's always our pleasure to be of assistance!
Sincerely, Linda Liu Microsoft Online Community Support
Richard - 30 Nov 2007 14:59 GMT Hello Linda,
The fix is OK until it made it to quality testing. The fix actually breaks icons in listviews and treeviews all over. Listviews that have icons now eeither do not show them altogether or show the wrong ones.
Please advise, thank you,
Richard
> Hi Richard, > [quoted text clipped - 12 lines] > Linda Liu > Microsoft Online Community Support Linda Liu[MSFT] - 03 Dec 2007 09:41 GMT Hi Richard,
I performed a test based on your description on my Windows XP machine and did see the problem.
I searched in our internal database and found that this is a known issue in Windows XP. The possible workaround to this problem would have been to custom draw the ListView control if the ListView in .NET 1.x supported custom drawing. Unfortunately, in fact the ListView in .NET 1.x doesn't support custom drawing at all.
I will consult this problem in our internal discussion group to see if there's any workaround.
In addition, if you could upgrade to .NET 2.0, the problem will not exist.
Sincerely, Linda Liu Microsoft Online Community Support
Richard - 03 Dec 2007 13:49 GMT Hello Linda,
Going to .NET 2.0 is not an option on this project. If it were, I'd already be on it :-)
It seems that doing a Application.DoEvents() right after the Application.EnableVisualStyles() before the creation of the main message loop has "resolved" the issue (up until QA gets their hands on it).
Please let me know of your internal discussion group outputs. Would this be the right time to talk about a hotfix?
Thank you
Richard
> Hi Richard, > [quoted text clipped - 15 lines] > Linda Liu > Microsoft Online Community Support Linda Liu[MSFT] - 07 Dec 2007 08:25 GMT Hi Richard,
I have received a reply from our internal discussion group. The reply said that this is an issue of common control v6 issue in .NET 1.1 applications.
Since calling Application.DoEvents after calling Application.EnableVisualStyles could solve the problem, a hot fix request would likely be rejected.
Thank you for sharing the workaround in the community. It will definitely benefit all of us!
If you have any other questions in the future, please don't hesitate to contact us. It's always our pleasure to be of assistance!
Have a nice weekend!
Sincerely, Linda Liu Microsoft Online Community Support
Richard - 07 Dec 2007 13:54 GMT Hello Linda,
Well, QA has already noticed some "side effects" of using EnableVisualStyles, just what does that do in regards to icons?
Richard
> Hi Richard, > [quoted text clipped - 16 lines] > Linda Liu > Microsoft Online Community Support Linda Liu[MSFT] - 10 Dec 2007 03:09 GMT Hi Richard,
Thank you for your feedback!
If an application is enabled visual styles by calling the Application.EnableVisualStyles, .NET Framework will draw controls with visual styles.
If there's a problem in drawing controls with visual styles, e.g. in our case, the icons don't appear in the ListView when the visual styles is enabled for the application, calling the Application.DoEvents can always solve the problem.
If you have any question, please feel free to let me know.
Sincerely, Linda Liu Microsoft Online Community Support
Richard - 11 Dec 2007 04:11 GMT Hello Linda,
Well, EnableVisualStyles does have a side effect with toolbars. The toolbar offers a property ButtonSize, which can be set when EnableVisualStyles is not called. When the EnableVisualStyles is called, the toolbar buttons simply ignore the specified size. They automatically get to be the size of the content of the toolbar button.
Please advise on how to not have unwanted side effect on the toolbar (buttons)...
Thank you,
Richard
> Hi Richard, > [quoted text clipped - 14 lines] > Linda Liu > Microsoft Online Community Support Linda Liu[MSFT] - 11 Dec 2007 10:14 GMT Hi Richard,
I performed a test on this issue and did reproduce the problem on my side.
I searched in our internal data base and found that this is a known issue. Unfortunately, there's no workaround so far.
I suggest that you use the Panel and Button to mimic the ToolBar, i.e. add some Buttons on a Panel and dock the Panel to the top of the form. If you don't like the Button to be rendered with visual styles, you may set the FlatStyle property of the Button to a value other than System.
Hope this helps.
If you have any concern, please feel free to let me know.
Sincerely, Linda Liu Microsoft Online Community Support
Richard - 11 Dec 2007 15:31 GMT Hello Linda,
Well, sure enough that a panel with buttons would do the job, but it just so happens I do not have control over that - the customer does not want to modify their applications and our framework broke it (by enabling visual styles).
What can be done in this case?
Thank you,
Richard
> Hi Richard, > [quoted text clipped - 15 lines] > Linda Liu > Microsoft Online Community Support Linda Liu[MSFT] - 13 Dec 2007 11:04 GMT Hi Richard,
Thank you for your feedback!
As we all know, to erase the flickering of the ListView in .NET 1.1, we have to use the version 6 ListView in the comctl6.dll(to do this, call the Application.EnableVisualStyles method).
However, the version 6 ToolBar has an problem that the ButtonSize property doesn't work and unfortunately there's no workaround so far.
IMO, even if there's a workaround for the ToolBar issue, your customer still need to modify their applications to apply this workaroud. In additon, I don't think it needs much modifications or efforts to use a Panel with some Buttons to replace the ToolBar.
Thank you for your understanding!
Sincerely, Linda Liu Microsoft Online Community Support
Richard - 13 Dec 2007 14:14 GMT Hello Linda,
Well, our framework "owns" the message loop creation (application.run), thereby we do the enablevisualstyles, which break their applications.
Anyhow, I'll what can be done...
Richard
> Hi Richard, > [quoted text clipped - 17 lines] > Linda Liu > Microsoft Online Community Support Linda Liu[MSFT] - 14 Dec 2007 10:44 GMT Hi Richard,
> Well, our framework "owns" the message loop creation (application.run) What's the "framework" you mentioned in the above sentence? What do you mean by "owns the message loop creation"?
> thereby we do the enablevisualstyles, which break their applications. Do you mean that you couldn't enable visual styles in the application because that would break the application?
Sincerely, Linda Liu Microsoft Online Community Support
Richard - 14 Dec 2007 14:22 GMT Well it is a catch22 - to solve the listview problem, I need to enablevisualstyles, but then that breaks their applications' icons.
"by framework" I mean a framework that we provide so that they can build their specialized applications.
> Hi Richard, > [quoted text clipped - 11 lines] > Linda Liu > Microsoft Online Community Support
Free MagazinesGet these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...
|
|
|