|
| Solution to ListView flicker |
|
|
|
|
| Messages |
|
Related Types |
This message was discovered on microsoft.public.dotnet.languages.csharp.
| peter |
| GOOD ANSWER |
The flicker in the .Net ListView control was driving me crazy. For every update to the control, the entire background was redrawn. There are many threads in this newsgroup about this issue (applies to TreeView as well), but so far none of the solutions have worked for me. This is what I came up with instead. It works beautifully and I haven't come across any drawbacks (no pun intended) yet.
The solution is to subclass the ListView control and filter out the WM_ERASEBKGND message. Here is the complete source for the subclassed control. Make a new UserControl, paste and compile. Good luck! - Peter.
using System; using System.Collections; using System.ComponentModel; using System.Drawing; using System.Data; using System.Windows.Forms;
namespace EnhancedControls { /// <summary> /// Summary description for UserControl1. /// </summary> public class FlickerFreeListView : System.Windows.Forms.ListView {
/// <summary> /// Required designer variable. /// </summary> private System.ComponentModel.Container components = null;
public FlickerFreeListView() { // This call is required by the Windows.Forms Form Designer. InitializeComponent();
// Activate double buffering SetStyle( ControlStyles.AllPaintingInWmPaint | ControlStyles.DoubleBuffer | ControlStyles.ResizeRedraw, true );
// Allows for catching the WM_ERASEBKGND message SetStyle( ControlStyles.EnableNotifyMessage, true); }
protected override void OnNotifyMessage (Message m) { // filter WM_ERASEBKGND if(m.Msg != 0x14) { base.OnNotifyMessage(m); } }
protected override void OnPaintBackground(PaintEventArgs pea) { // do nothing here since this event is now handled by OnPaint }
protected override void OnPaint(PaintEventArgs pea) { base.OnPaint(pea); }
/// <summary> /// Clean up any resources being used. /// </summary> protected override void Dispose( bool disposing ) { if( disposing ) { if( components != null ) components.Dispose(); } base.Dispose( disposing ); }
#region Component Designer generated code /// <summary> /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// </summary> private void InitializeComponent() { components = new System.ComponentModel.Container(); } #endregion } }
|
|
|
| |
|
|
| |
| |
| Nicholas Paldino [.NET/C# MVP] |
Peter,
How many updates are you performing? By update, I assume that you mean adding items to the ListView and TreeView classes. If this is the case, when you have a large number of items to be added, why not call the BeginUpdate and EndUpdate methods?
Hope this helps.
-- - Nicholas Paldino [.NET MVP] - Click here to reveal e-mail address
"peter" <Click here to reveal e-mail address> wrote in message news:H0gW8.3123$Click here to reveal e-mail address... [Original message clipped]
|
|
|
| |
|
| |
| |
| peter |
The ListView is already populated with 3000 items. Five separate background threads are iterating through the items and updating two fields (subitems). I have tried BeginUpdate and EndUpdate, but they had no effect at all. The ListView is in Details view.
Peter.
"Nicholas Paldino [.NET/C# MVP]" <Click here to reveal e-mail address> wrote in message news:OOvF8OoJCHA.2516@tkmsftngp11... [Original message clipped]
|
|
|
| |
|
|
| |
| |
| Nicholas Paldino [.NET/C# MVP] |
Peter,
When you are adding the items, and making the calls to BeginUpdate and EndUpdate, are they on the worker threads or on the UI thread? If they are on the worker threads, then the calls are unpredictable. The calls should be made through a call to a delegate using the Invoke method on the ListView/TreeView instance.
-- - Nicholas Paldino [.NET MVP] - Click here to reveal e-mail address
"peter" <Click here to reveal e-mail address> wrote in message news:SQgW8.3135$Click here to reveal e-mail address... > The ListView is already populated with 3000 items. Five separate background > threads are iterating through the items and updating two fields (subitems). [Original message clipped]
|
|
|
| |
|
| |
| |
| peter |
Thanks for the info.
I am using _ui.BeginInvoke from my worker thread to send the updated data to a delegate in the form of custom ThreadEventArgs. The delegate is defined in the main UI thread (in the main form).
I tried Invoke instead of BeginInvoke, but that made it slightly worse.
Peter.
"Nicholas Paldino [.NET/C# MVP]" <Click here to reveal e-mail address> wrote in message news:eHZRJgoJCHA.1596@tkmsftngp13... [Original message clipped]
|
|
|
| |
|
| |
|
|
|
|
| |
| Hendrik Wiese |
I tried it but the background of the new ListView is all black and so no item is visible. They are all there 'cos the ListView can scroll up and down and I can select items. But I can't see any since background of the control is all black.
What's the problem here?
Thankx!
-------------------------------- From: Hendrik Wiese
|
|
|
| |
|
|
| |
|
|
|
|
|
|
|
|
BootFX
Reliable and powerful .NET application framework. |
|
|
|
|
|
|