在ListView控件中闪烁(OwnerDraw,Virtual)
此问题可能被视为使用ownerdraw和virtualmode在listview中闪烁的后续行动。
我在Virtual mode
有一个ListView
控件,我尝试执行自定义绘图。 项目渲染通过以下方法覆盖完成:
protected override void OnDrawItem(DrawListViewItemEventArgs eventArgs)
如引用的问题所述,自定义绘图会在鼠标hover事件上引入闪烁。 调试器告诉我这是由于过多的自定义绘制事件被触发而发生的。
现在 – 引用问题的接受答案告诉我们:
这是.NET的ListView中的一个错误,你不能通过双缓冲绕过它。
我在任何自定义渲染事件处理程序(DrawItem,DrawSubItem)中都看到了ListView控件的这个闪烁问题。 我尝试了BeginUpdate()/ EndUpdate()和双缓冲没有成功。 我认为.NET会向自定义绘制列右侧的所有列触发其他WM_PAINT。
但是我发现这个解决方法是一个自定义渲染列ListView。 它工作得很好!
- 在columnheader编辑器中,将自定义绘制列设置为最后一列
- 更改所需位置的“DisplayIndex”
这应该可以解决鼠标hover或运行时渲染中的闪烁问题。
至少对于OnDrawItem的双缓冲,有一个错误是错误的,但它有点愚蠢:你可以设置一个受保护的属性,但你需要覆盖ListView。 我创建了这种类:
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()
将解决问题。
关于这个的MSDN主题
也许以这种方式:
protected override void OnDrawItem(DrawListViewItemEventArgs eventArgs) { ListView.BeginUpdate(); //Do Works Here ListView.EndUpdate(); }
更新
另一个替代方案可能是在BackgroundWorker
使用一个新的线程来更新ListView …我在我的应用程序中实现了这个以及BeginUpdate()
/ EndUpDate()
,发现它比只有BeginUpdate()
/ EndUpDate()
速度快。
更新
我在SO发现了另一个有效的解决方案 ,一个由Brian Gillespie
提供的助手类:
上述就是C#学习教程:在ListView控件中闪烁(OwnerDraw,Virtual)分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)
public enum ListViewExtendedStyles { /// /// LVS_EX_GRIDLINES /// GridLines = 0x00000001, /// /// LVS_EX_SUBITEMIMAGES /// SubItemImages = 0x00000002, /// /// LVS_EX_CHECKBOXES /// CheckBoxes = 0x00000004, /// /// LVS_EX_TRACKSELECT /// TrackSelect = 0x00000008, /// /// LVS_EX_HEADERDRAGDROP /// HeaderDragDrop = 0x00000010, /// /// LVS_EX_FULLROWSELECT /// FullRowSelect = 0x00000020, /// /// LVS_EX_ONECLICKACTIVATE /// OneClickActivate = 0x00000040, /// /// LVS_EX_TWOCLICKACTIVATE /// TwoClickActivate = 0x00000080, /// /// LVS_EX_FLATSB /// FlatsB = 0x00000100, /// /// LVS_EX_REGIONAL /// Regional = 0x00000200, /// /// LVS_EX_INFOTIP /// InfoTip = 0x00000400, /// /// LVS_EX_UNDERLINEHOT /// UnderlineHot = 0x00000800, /// /// LVS_EX_UNDERLINECOLD /// UnderlineCold = 0x00001000, /// /// LVS_EX_MULTIWORKAREAS /// MultilWorkAreas = 0x00002000, /// /// LVS_EX_LABELTIP /// LabelTip = 0x00004000, /// /// LVS_EX_BORDERSELECT /// BorderSelect = 0x00008000, /// /// LVS_EX_DOUBLEBUFFER /// DoubleBuffer = 0x00010000, /// /// LVS_EX_HIDELABELS /// HideLabels = 0x00020000, /// /// LVS_EX_SINGLEROW /// SingleRow = 0x00040000, /// /// LVS_EX_SNAPTOGRID /// SnapToGrid = 0x00080000, /// /// LVS_EX_SIMPLESELECT /// SimpleSelect = 0x00100000 } public enum ListViewMessages { First = 0x1000, SetExtendedStyle = (First + 54), GetExtendedStyle = (First + 55), } /// /// Contains helper methods to change extended styles on ListView, including enabling double buffering. /// Based on Giovanni Montrone's article on /// 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); } }
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请点击右边联系管理员删除。
如若转载,请注明出处:https://www.ctvol.com/cdevelopment/1024699.html