C# 更新时闪烁Listview
我有一个定期更新的列表视图(每 60 秒)。 每次更新时我都会闪烁,这让我很恼火。 使用的方法是清除所有项目,然后重新创建它们。 我决定不清除这些项目,而直接将新文本写入单元格。 这是更好的方法还是有人有更好的解决方案。
I have a list view that is periodically updated (every 60 seconds). It was anoying to me that i would get a flicker every time it up dated. The method being used was to clear all the items and then recreate them. I decided to instead of clearing the items I would just write directly to the cell with the new text. Is this a better approach or does anyone have a better solution.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(15)
是的,使其双缓冲。 它将减少闪烁;) http:// msdn.microsoft.com/en-us/library/system.windows.forms.listview.doublebuffered.aspx
Yes, make it double buffered. It will reduce the flicker ;) http://msdn.microsoft.com/en-us/library/system.windows.forms.listview.doublebuffered.aspx
很好的问题,Stormenent 的回答很准确。 这是他的代码的 C++ 移植版,供其他可能处理 C++/CLI 实现的人使用。
Excellent question and Stormenent's answer was spot on. Here's a C++ port of his code for anyone else who might be tackling C++/CLI implementations.
您可以使用以下扩展类将
DoubleBuffered
属性设置为true
:You can use the following extension class to set the
DoubleBuffered
property totrue
:最简单的解决方案可能是使用
而不是
这样效果更好。
The simplest Solution would probably be using
instead of
This works way better.
简单的解决方案
Simple solution
我知道这是一个极其古老的问题和答案。 然而,这是搜索“C++/cli listview flicker”时的最高结果 - 尽管事实上这甚至不是在谈论 C++。 所以这里是这个的 C++ 版本:
我把它放在我的主窗体的头文件中,您可以选择将它放在其他地方...
如果您碰巧在这里寻找托管 C++ 的类似答案,这对我有用。 :)
I know this is an extremely old question and answer. However, this is the top result when searching for "C++/cli listview flicker" - despite the fact that this isn't even talking about C++. So here's the C++ version of this:
I put this in the header file for my main form, you can choose to put it elsewhere...
If you happen to land here looking for a similar answer for managed C++, that works for me. :)
这对我来说效果最好。
由于您直接编辑单元格,因此您的情况的最佳解决方案是简单地刷新/重新加载该特定单元格/行而不是整个表格。
您可以使用
RedrawItems(...)
方法,该方法基本上仅重新绘制列表视图的指定范围的项目/行。参考
这完全消除了我的完整列表视图闪烁。
只有相关项目/记录在更新时才会闪烁。
干杯!
This worked best for me.
Since you are editing the cell directly, the best solution in your case would be to simply refresh/reload that particular cell/row instead of the entire table.
You could use the
RedrawItems(...)
method that basically repaints only the specified range of items/rows of the listview.Reference
This totally got rid of the full listview flicker for me.
Only the relevant item/record flickers while getting updated.
Cheers!
如果有人仍然想找到这个问题的答案,我使用了一个计时器来稍微延迟一下,它很好地解决了这个问题。 我想在鼠标移动事件上突出显示(更改颜色)整行,但我认为它适用于项目替换等。对我来说 listView.BeginUpdate() 和 listView.EndUpdate() 不起作用,DoubleBuffered 属性也不起作用没用,我用谷歌搜索了很多,但没有任何效果。
If someone would still look an answer for this, I used a timer for a slight delay and it solved the problem nicely. I wanted to highlight (change colour) for the entire row on mouse move event, but I think it would work for item replacement etc. For me listView.BeginUpdate() and listView.EndUpdate() didn't work, DoubleBuffered property also didn't work, I have googled a lot and nothing worked.
尝试将双缓冲属性设置为 true。
您也可以使用:
Try setting the double buffered property in true.
Also you could use:
在 Winrt Windows Phone 8.1 中,您可以设置以下代码来解决此问题。
In Winrt Windows phone 8.1 you can set the following code to fix this issue.
对于它的价值,就我而言,我只需添加一个调用
在运行应用程序之前
,如下所示:否则,双缓冲是不够的。 也许这是一个非常古老的项目,而新项目默认具有该设置......
For what it's worth, in my case, I simply had to add a call to
before running the application, like this:
Otherwise, double buffering is not enough. Maybe it was a very old project and new ones have that setting by default...
ListView控件存在闪烁问题。 问题似乎是控件的更新重载未正确实现,使其行为类似于刷新。 更新应该导致控件仅重绘其无效区域,而刷新则重绘控件的整个工作区。 因此,如果您要更改列表中一项的背景颜色,则只需重新绘制该特定项。 不幸的是,ListView 控件似乎有不同的意见,并且每当您弄乱单个项目时都希望重新绘制其整个表面......即使该项目当前未显示。 因此,无论如何,您可以通过如下方式轻松抑制闪烁:
来自: Geekswithblogs.net
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:
From: Geekswithblogs.net
这是我对 C# 实现的快速修复,不需要对列表视图等进行子类化。
使用反射在表单构造函数中将 DoubleBuffered 属性设置为 true。
2021 年更新:
我在这篇旧帖子上收到了一条评论,现在我会以不同的方式编写这段代码。 下面是一个扩展方法,它将向 ListView 添加一个新方法,以便能够根据需要将双缓冲属性设置为 true/false。 然后,这将扩展所有列表视图并使其更容易根据需要进行调用。
Here is my quick fix for a C# implementation that does not require subclassing the list views etc.
Uses reflection to set the DoubleBuffered Property to true in the forms constructor.
Update for 2021:
I got pinged on this old post with a comment and I would write this code differently now. Below is an extension method that will add a new method to a ListView to be able to set the double buffered property to true/false as required. This will then extend all list views and make it easier to call as reqired.
除了其他回复之外,许多控件还有一个
[Begin|End]Update()
方法,您可以使用该方法在编辑内容时减少闪烁 - 例如:In addition to the other replies, many controls have a
[Begin|End]Update()
method that you can use to reduce flickering when editing the contents - for example:如果这可以帮助,以下组件解决了我在 .NET 3.5 中的 ListView 闪烁问题,
我将它与 .BeginUpdate() 和 .EndUpdate() 方法结合使用,在其中进行 ListView.Items 操作。
我不明白为什么这个属性是受保护的......即使在 .NET 4.5 中(也许是一个安全问题)
If this can help, the following component solved my ListView flickering issues with .NET 3.5
I use it in conjonction with .BeginUpdate() and .EndUpdate() methods where I do ListView.Items manipulation.
I don't understand why this property is a protected one...even in the .NET 4.5 (maybe a security issue)