Blinkinginlistviewusingownerdrawandvirtualmode这。listView1.Columns.AddRange(newSystem.Windows.Forms.ColumnHeader[]{this.columnHeader1,this.columnHeader2});this.listView1.FullRowSelect=true;this.listView1.HideSelection=false;this.listView1.Location=newSystem.Drawing.Point(67,192);this.listView1.Name="listView1";this.listView1.Size=newSystem.Drawing.Size(438,236);this.listView1.TabIndex=0;this.listView1.UseCompatibleStateImageBehavior=false;this.listView1.View=System.Windows.Forms.View.Details;this.listView1.DrawColumnHeader+=newSystem.Windows.Forms.DrawListViewColumnHeaderEventHandler(this.listView1_DrawColumnHeader);this.listView1.RetrieveVirtualItem+=newSystem.Windows.Forms.RetrieveVirtualItemEventHandler(this.listView1_RetrieveVirtualItem);this.listView1.DrawSubItem+=newSystem.Windows.Forms.DrawListViewSubItemEventHandler(this.listView1_DrawSubItem);两行提供了一些随机文本所有者绘图很简单:e.DrawText();}否则e.DrawDefault=true;//Console.WriteLine("{0}ttBounds:{1}tItem:{2}tSubitem:{3}",(i++).ToString(),e.Bounds.ToString(),e.Item,e.SubItem);问题是:当我将鼠标悬停在列表视图的内容上时,我看到第一列闪烁。调试显示DrawSubItem在鼠标悬停时不断被调用。这是一个错误吗?如何避免这种行为?这是.NET的ListView中的一个错误,您无法通过双缓冲绕过它。在虚拟列表上,当鼠标悬停在第0列上时,基础控件会生成大量自定义绘制事件。即使启用了DoubleBuffering,这些自定义绘制事件也会导致闪烁,因为它们是在正常WmPaint消息之外发送的。我似乎还记得这只发生在XP上。Vista解决了这个问题(但引入了其他问题)。你可以看看ObjectListView中的代码,看看它是如何解决这个问题的。如果您想自己弄清楚,则需要深入研究ListView控件的内部管道:覆盖WndProc拦截WmPaint消息,并在msg拦截WmCustomDraw消息期间设置一个为真的标志,并忽略发生在外部的所有消息WmPaint事件。像这样的东西::protectedoverridevoidWndProc(refMessagem){switch(m.Msg){case0x0F://WM_PAINTthis.isInWmPaintMsg=true;base.WndProc(refm);this.isInWmPaintMsg=false;休息;case0x204E://WM_REFLECT_NOTIFYNativeMethods.NMHDRnmhdr=(NativeMethods.NMHDR)m.GetLParam(typeof(NativeMethods.NMHDR));if(nmhdr.code==-12){//NM_CUSTOMDRAWif(this.isInWmPaintMsg)base.WndProc(refm);}elsebase.WndProc(refm);休息;默认值:base.WndProc(refm);休息;我得到一堆'System.Drawing.NativeMethods'isunaccessibleduetoitsprotectionlevelandThetypename'NMHDR'doesnotexistinthetype'System.Drawing.NativeMethods'错误。我在某处读到我必须包含user32.dll但无法弄清楚在这种情况下该怎么做。编辑:好的,我什至在发帖前就开始思考了。我现在已经创建了自己的ListView控件并从objectListView代码中复制了结构。它现在似乎工作。这是我的代码:publicclassListview:ListView{privateboolisInWmPaintMsg=false;[StructLayout(LayoutKind.Sequential)]publicstructNMHDR{publicIntPtrhwndFrom;公共IntPtridFrom;公共整数代码;}protectedoverridevoidWndProc(refMessagem){switch(m.Msg){case0x0F://WM_PAINTthis.isInWmPaintMsg=true;base.WndProc(refm);this.isInWmPaintMsg=false;休息;案例0x204E://WM_REFLECT_NOTIFYNMHDRnmhdr=(NMHDR)m.GetLParam(typeof(NMHDR));if(nmhdr.code==-12){//NM_CUSTOMDRAWif(this.isInWmPaintMsg)base.WndProc(refm);}elsebase.WndProc(refm);休息;默认值:base.WndProc(refm);休息;}}}我不能经常为调用自定义绘制事件的ListView提出解决方案,但也许您可以通过双缓冲来掩盖问题:Stackoverflow:Howtodoublebuffer.NETonaformcontrols?以上就是C#学习教程:使用ownerdraw和virtualmode刷机共享listview中的所有内容。如果对你有用,需要进一步了解C#学习教程,希望大家多多关注。本文收集自网络,不代表立场。涉及侵权,请点击维权联系管理员删除。如需转载请注明出处:
