How to prevent flickering in ListView when updating a single ListViewItem's text?
To end this question, here is a helper class that should be called when the form is loading for each ListView or any other ListView's derived control in your form. Thanks to "Brian Gillespie" for giving the solution.
public enum ListViewExtendedStyles
{
/// <summary>
/// LVS_EX_GRIDLINES
/// </summary>
GridLines = 0x00000001,
/// <summary>
/// LVS_EX_SUBITEMIMAGES
/// </summary>
SubItemImages = 0x00000002,
/// <summary>
/// LVS_EX_CHECKBOXES
/// </summary>
CheckBoxes = 0x00000004,
/// <summary>
/// LVS_EX_TRACKSELECT
/// </summary>
TrackSelect = 0x00000008,
/// <summary>
/// LVS_EX_HEADERDRAGDROP
/// </summary>
HeaderDragDrop = 0x00000010,
/// <summary>
/// LVS_EX_FULLROWSELECT
/// </summary>
FullRowSelect = 0x00000020,
/// <summary>
/// LVS_EX_ONECLICKACTIVATE
/// </summary>
OneClickActivate = 0x00000040,
/// <summary>
/// LVS_EX_TWOCLICKACTIVATE
/// </summary>
TwoClickActivate = 0x00000080,
/// <summary>
/// LVS_EX_FLATSB
/// </summary>
FlatsB = 0x00000100,
/// <summary>
/// LVS_EX_REGIONAL
/// </summary>
Regional = 0x00000200,
/// <summary>
/// LVS_EX_INFOTIP
/// </summary>
InfoTip = 0x00000400,
/// <summary>
/// LVS_EX_UNDERLINEHOT
/// </summary>
UnderlineHot = 0x00000800,
/// <summary>
/// LVS_EX_UNDERLINECOLD
/// </summary>
UnderlineCold = 0x00001000,
/// <summary>
/// LVS_EX_MULTIWORKAREAS
/// </summary>
MultilWorkAreas = 0x00002000,
/// <summary>
/// LVS_EX_LABELTIP
/// </summary>
LabelTip = 0x00004000,
/// <summary>
/// LVS_EX_BORDERSELECT
/// </summary>
BorderSelect = 0x00008000,
/// <summary>
/// LVS_EX_DOUBLEBUFFER
/// </summary>
DoubleBuffer = 0x00010000,
/// <summary>
/// LVS_EX_HIDELABELS
/// </summary>
HideLabels = 0x00020000,
/// <summary>
/// LVS_EX_SINGLEROW
/// </summary>
SingleRow = 0x00040000,
/// <summary>
/// LVS_EX_SNAPTOGRID
/// </summary>
SnapToGrid = 0x00080000,
/// <summary>
/// LVS_EX_SIMPLESELECT
/// </summary>
SimpleSelect = 0x00100000
}
public enum ListViewMessages
{
First = 0x1000,
SetExtendedStyle = (First + 54),
GetExtendedStyle = (First + 55),
}
/// <summary>
/// Contains helper methods to change extended styles on ListView, including enabling double buffering.
/// Based on Giovanni Montrone's article on <see cref="http://www.codeproject.com/KB/list/listviewxp.aspx"/>
/// </summary>
public class ListViewHelper
{
private ListViewHelper()
{
}
[DllImport("user32.dll", CharSet = CharSet.Auto)]
private static extern int SendMessage(IntPtr handle, int messg, int wparam, int lparam);
public static void SetExtendedStyle(Control control, ListViewExtendedStyles exStyle)
{
ListViewExtendedStyles styles;
styles = (ListViewExtendedStyles)SendMessage(control.Handle, (int)ListViewMessages.GetExtendedStyle, 0, 0);
styles |= exStyle;
SendMessage(control.Handle, (int)ListViewMessages.SetExtendedStyle, 0, (int)styles);
}
public static void EnableDoubleBuffer(Control control)
{
ListViewExtendedStyles styles;
// read current style
styles = (ListViewExtendedStyles)SendMessage(control.Handle, (int)ListViewMessages.GetExtendedStyle, 0, 0);
// enable double buffer and border select
styles |= ListViewExtendedStyles.DoubleBuffer | ListViewExtendedStyles.BorderSelect;
// write new style
SendMessage(control.Handle, (int)ListViewMessages.SetExtendedStyle, 0, (int)styles);
}
public static void DisableDoubleBuffer(Control control)
{
ListViewExtendedStyles styles;
// read current style
styles = (ListViewExtendedStyles)SendMessage(control.Handle, (int)ListViewMessages.GetExtendedStyle, 0, 0);
// disable double buffer and border select
styles -= styles & ListViewExtendedStyles.DoubleBuffer;
styles -= styles & ListViewExtendedStyles.BorderSelect;
// write new style
SendMessage(control.Handle, (int)ListViewMessages.SetExtendedStyle, 0, (int)styles);
}
}
c# flickering Listview on update
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);
}
}
}
From: Geekswithblogs.net
Cannot get ListView to stop flickering
Subclass ListView to enable double buffering:
namespace System.Windows.Forms
{
public class ListViewEx : ListView
{
protected override CreateParams CreateParams
{
get
{
CreateParams cp = base.CreateParams;
cp.ExStyle |= 0x02000000; // Turn on WS_EX_COMPOSITED
return cp;
}
}
}
}
Prevent flickering in ListView
I quickly ran through that anwser and i suspect that calling the EnableDoubleBuffer(myListVeiew);
should be what you're looking for...
Blurry Text with C# Listview when reducing flicker
I usually do this - reduces flickering when resizing the control. You need to use BeginUpdate()
/ EndUpdate()
to reduce flickering when adding items in bulk. I don't know what may cause the blurring, so I can't advise about that - updatig your video driver may help but don't hold your hopes high.
[System.ComponentModel.DesignerCategory ( "" )]
public partial class ListViewEx : ListView
{
private const int WM_ERASEBKGND = 0x14;
public ListViewEx ()
{
InitializeComponent ();
// Turn on double buffering.
SetStyle ( ControlStyles.OptimizedDoubleBuffer |
ControlStyles.AllPaintingInWmPaint, true );
// Enable the OnNotifyMessage to filter out Windows messages.
SetStyle ( ControlStyles.EnableNotifyMessage, true );
}
protected override void OnNotifyMessage ( Message oMsg )
{
// Filter out the WM_ERASEBKGND message to prevent the control
// from erasing the background (and thus avoid flickering.)
if ( oMsg.Msg != WM_ERASEBKGND )
base.OnNotifyMessage ( oMsg );
}
}
Flickering in ListView control (OwnerDraw, Virtual)
I've seen this flickering issue with ListView control in any custom rendering event handlers (DrawItem, DrawSubItem). I tried BeginUpdate()/EndUpdate() and double buffering with no success. I think .NET triggers additional WM_PAINT to all columns to the right of the custom drawn column.
However I found this workaround to a single custom rendered column ListView. It works just fine!
- In the columnheader editor, set the custom drawn column as the last column
- Change the "DisplayIndex" of the position you want
This should solve the flickering in mouseover or run-time rendering.
Related Topics
How to Define a Method in Razor
Keep Window on Top and Steal Focus in Winforms
What Is the C# Equivalent of Nan or Isnumeric
How to Run Multiple SQL Commands in a Single SQL Connection
How to Extend Identityuser with Custom Property
Compile and Run Dynamic Code, Without Generating Exe
What Do Programmers Mean When They Say, "Code Against an Interface, Not an Object."
Redirect Console.Writeline from Windows Application to a String
How to Retrieve the Loaderexception Property
C#7: Underscore ( _ ) & Star ( * ) in Out Variable
How to Detect If a Debugger Is Attached to Another Process from C#
How to List All Loaded Assemblies
Nested "From" Linq Query Expressed with Extension Methods
Autonumber with Entity Framework
C# - Set Directory Permissions for All Users in Windows 7
Using Mediaelement to Play Video from Stream
Get All Registered Routes in ASP.NET Core
How to Set Up Httpcontent for My Httpclient Postasync Second Parameter