C# ListView控件中闪烁(OwnerDraw,虚拟)
这一问题可被视为对这一问题的后续行动 我在C# ListView控件中闪烁(OwnerDraw,虚拟),c#,winforms,listview,flicker,ownerdrawn,C#,Winforms,Listview,Flicker,Ownerdrawn,这一问题可被视为对这一问题的后续行动 我在虚拟模式下有一个列表视图控件,我尝试执行自定义绘图。项目渲染通过以下方法完成: protected override void OnDrawItem(DrawListViewItemEventArgs eventArgs) 如参考问题中所述,自定义图形引入鼠标悬停事件时的闪烁。调试器告诉我,这是由于触发了过多的自定义绘制事件造成的 现在-参考问题的公认答案告诉我们: 这是.NET的ListView中的一个bug,您无法通过 双缓冲 那么,这些信息
虚拟模式下有一个列表视图
控件
,我尝试执行自定义绘图。项目渲染通过以下方法完成:
protected override void OnDrawItem(DrawListViewItemEventArgs eventArgs)
如参考问题中所述,自定义图形引入鼠标悬停事件时的闪烁。调试器告诉我,这是由于触发了过多的自定义绘制事件造成的
现在-参考问题的公认答案告诉我们: 这是.NET的ListView中的一个bug,您无法通过 双缓冲
- 那么,这些信息有多可靠?这真的是一个bug吗?或者我们只是试图切断一部分信息,希望它不会改变可见的行为
- 如果我在
我可以抑制这些虚拟模式下为
设置了我的所有者绘图例程,列表视图
事件,并且只在自定义绘图
中执行绘图,这是真的吗?或者,在某些情况下可能不正确WM_PAINT
控件能够在System.Windows.Forms
中进行所有绘制而不改变其初始行为的先决条件是什么WM\u PAINT
public class MyListView : ListView
{
public MyListView()
: base()
{
DoubleBuffered = true;
}
}
然后在MyForm.Designer.cs文件中,我用以下行更改ListView的实例化:
private ListView myListView;
this.myListView = new MyListView();
OnDrawItem将像一个符咒一样工作 比如,虽然不确定,但是
我认为ListView.BeginUpdate()
和ListView.EndUpdate()
将解决这个问题
也许是这样:
protected override void OnDrawItem(DrawListViewItemEventArgs eventArgs)
{
ListView.BeginUpdate();
//Do Works Here
ListView.EndUpdate();
}
更新
另一种选择可能是使用BackgroundWorker
中的新线程更新ListView。。。
我在应用程序中与BeginUpdate()
/EndUpDate()
一起实现了这一点,发现它比BeginUpdate()
/EndUpDate()
要快得多
更新
我找到了另一个正在工作的助手类,它是由Brian Gillespie
提供的:
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);
}
}
公共枚举ListViewExtendedStyles
{
///
///LVS_EX_网格线
///
网格线=0x00000001,
///
///LVS_EX_子项图像
///
子项图像=0x00000002,
///
///LVS_EX_复选框
///
复选框=0x00000004,
///
///LVS_EX_轨迹选择
///
TrackSelect=0x00000008,
///
///LVS_EX_HEADERDRAGDROP
///
HeaderDragDrop=0x00000010,
///
///LVS_EX_FULLROWSELECT
///
FullRowSelect=0x00000020,
///
///LVS_EX_One单击激活
///
OneClickActivate=0x00000040,
///
///LVS_EX_Two单击激活
///
两次单击激活=0x00000080,
///
///LVS_EX_FLATSB
///
FlatsB=0x00000100,
///
///LVS_前_地区
///
区域=0x00000200,
///
///LVS_EX_信息提示
///
InfoTip=0x00000400,
///
///LVS_EX_UNDERLINEHOT
///
下划线HOT=0x00000800,
///
///LVS_EX_UNDERLINECOLD
///
下划线COLD=0x00001000,
///
///LVS_EX_多工作区
///
多工作区=0x000020000,
///
///LVS_EX_LABELTIP
///
LabelTip=0x00004000,
///
///LVS_EX_BORDERSELECT
///
BorderSelect=0x00008000,
///
///LVS_EX_双缓冲区
///
DoubleBuffer=0x00010000,
///
///LVS_EX_HIDELABELS
///
HideLabels=0x00020000,
///
///LVS_EX_SINGLEROW
///
单行=0x00040000,
///
///LVS_EX_SNAPTOGRID
///
SnapToGrid=0x00080000,
///
///LVS_EX_SIMPLESELECT
///
SimpleSelect=0x00100000
}
公共枚举ListViewMessages
{
第一个=0x1000,
SetExtendedStyle=(第一个+54),
GetExtendedStyle=(第一个+55),
}
///
///包含用于更改ListView上扩展样式的帮助器方法,包括启用双缓冲。
///根据Giovanni Montrone关于
///
公共类ListViewHelper
{
私有ListViewHelper()
{
}
[DllImport(“user32.dll”,CharSet=CharSet.Auto)]
私有静态外部int SendMessage(IntPtr句柄、int messg、int wparam、int lparam);
公共静态void SetExtendedStyle(控件控件,ListViewExtendedStyles exStyle)
{
ListViewExtendedStyles;
styles=(ListViewExtendedStyles)SendMessage(control.Handle,(int)ListViewMessages.GetExtendedStyle,0,0);
样式|=exStyle;
SendMessage(control.Handle,(int)ListViewMessages.SetExtendedStyle,0,(int)styles);
}
公共静态无效启用DoubleBuffer(控制)
{
ListViewExtendedStyles;
//阅读当前样式
styles=(ListViewExtendedStyles)SendMessage(control.Handle,(int)ListViewMessages.GetExtendedStyle,0,0);
//启用双缓冲区和边框选择
styles |=ListViewExtendedStyles.DoubleBuffer | ListViewExtendedStyles.BorderSelect;
//写新文体
SendMessage(control.Handle,(int)ListViewMessages.SetExtendedStyle,0,(int)styles);
}
公共静态无效禁用DoubleBuffer(控制)
{
ListViewExtendedStyles;
//阅读当前样式
styles=(ListViewExtendedStyles)SendMessage(control.Handle,(int)ListViewMessages.GetExtendedStyle,0,0);
//禁用双缓冲区和边框选择
样式-=样式和ListViewExtendedStyles.DoubleBuffer;
样式-=样式和列表视图ExtendedStyles.BorderSelect;
//写新文体
SendMessage(control.Handle,(int)ListViewMessages.SetExtendedStyle,0,(int)styles);
}
}
我看到这个闪烁不定