Bra*_*rad 50 c# listview flicker
我有一个定期更新的列表视图(每60秒).对我来说很烦人,每当它过时都会闪烁.使用的方法是清除所有项目,然后重新创建它们.我决定不使用新文本清除直接写入单元格的项目.这是一种更好的方法,还是有人有更好的解决方案.
Sto*_*net 91
ListView控件有一个闪烁问题.问题似乎是控件的Update重载不正确地实现,使其像Refresh一样运行.更新应该使控件仅重绘其无效区域,而刷新重绘控件的整个客户区域.因此,如果您要更改列表中某个项目的背景颜色,则只需要重新绘制该特定项目.不幸的是,ListView控件似乎有不同的意见,并且想要在你弄乱单个项目时重新绘制整个表面......即使当前没有显示该项目.所以,无论如何,您可以通过滚动自己来轻松抑制闪烁,如下所示:
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);
}
}
}
Run Code Online (Sandbox Code Playgroud)
Mar*_*ell 22
除了其他回复之外,许多控件都有一种[Begin|End]Update()方法可用于在编辑内容时减少闪烁 - 例如:
listView.BeginUpdate();
try {
// listView.Items... (lots of editing)
} finally {
listView.EndUpdate();
}
Run Code Online (Sandbox Code Playgroud)
这是我的C#实现的快速解决方案,该实现不需要子类化列表视图等。
使用反射将DoubleBuffered属性设置为尝试在窗体构造函数中使用。
lvMessages
.GetType()
.GetProperty("DoubleBuffered", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic)
.SetValue(lvMessages, true, null);
Run Code Online (Sandbox Code Playgroud)
是的,让它双倍缓冲.它会减少闪烁;)http://msdn.microsoft.com/en-us/library/system.windows.forms.listview.doublebuffered.aspx
精彩的问题和Stormenent的答案就在现场。这是他的代码的C ++端口,适合可能正在解决C ++ / CLI实现的其他任何人。
#pragma once
#include "Windows.h" // For WM_ERASEBKGND
using namespace System;
using namespace System::Windows::Forms;
using namespace System::Data;
using namespace System::Drawing;
public ref class FlickerFreeListView : public ListView
{
public:
FlickerFreeListView()
{
//Activate double buffering
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
SetStyle(ControlStyles::EnableNotifyMessage, true);
}
protected:
virtual void OnNotifyMessage(Message m) override
{
//Filter out the WM_ERASEBKGND message
if(m.Msg != WM_ERASEBKGND)
{
ListView::OnNotifyMessage(m);
}
}
};
Run Code Online (Sandbox Code Playgroud)
如果这可以解决问题,则以下组件解决了.NET 3.5的ListView闪烁问题。
[ToolboxItem(true)]
[ToolboxBitmap(typeof(ListView))]
public class ListViewDoubleBuffered : ListView
{
public ListViewDoubleBuffered()
{
this.DoubleBuffered = true;
}
}
Run Code Online (Sandbox Code Playgroud)
我将它与ListView.Items操作的.BeginUpdate()和.EndUpdate()方法配合使用。
我不明白为什么此属性是受保护的属性...即使在.NET 4.5中(可能是安全问题)
| 归档时间: |
|
| 查看次数: |
46397 次 |
| 最近记录: |