树视图闪烁
本文关键字:闪烁 视图 | 更新日期: 2023-09-27 18:32:27
我开始知道,通过添加TreeView.BeginUpdate可以防止treeview闪烁,但是当我将其添加到我的项目中时,我的treeview的所有节点都消失了,任何人都可以告诉我为什么会发生这种情况,这是我使用TreeView.BeginUpdate和TreeView.EndUpdate的代码片段。
TreeNode treeNode = new TreeNode("Windows");
treeView1.Nodes.Add(treeNode);
//
// Another node following the first node.
//
treeNode = new TreeNode("Linux");
treeView1.Nodes.Add(treeNode);
//
// Create two child nodes and put them in an array.
// ... Add the third node, and specify these as its children.
//
TreeNode node2 = new TreeNode("C#");
TreeNode node3 = new TreeNode("VB.NET");
TreeNode[] array = new TreeNode[] { node2, node3 };
//
// Final node.
//
treeNode = new TreeNode("Dot Net Perls", array);
treeView1.Nodes.Add(treeNode);
Begin/EndUpdate() 方法不是为了消除闪烁而设计的。 在 EndUpdate() 上闪烁是不可避免的,它会重新绘制控件。 它们旨在加快添加大量节点的速度,默认情况下会很慢,因为每个项目都会导致重新绘制。 你把它们放在for循环中,把它们移到外面立即改进,使情况变得更糟。
这可能足以解决您的问题。 但你可以让它变得更好,抑制闪烁需要双重缓冲。 类重写双缓冲属性并将其隐藏。 这是一个历史事故,本机Windows控件仅支持Windows XP及更高版本中的双缓冲。 .NET 曾经支持 Windows 2000 和 Windows 98。
如今,这已经不再完全相关了。 可以通过从 TreeView 派生自己的类来将其放回原处。 向项目添加新类并粘贴如下所示的代码。 编译。 将新控件从工具箱顶部拖放到窗体上,替换现有的树视图。 效果非常明显,尤其是在滚动时。
using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;
class BufferedTreeView : TreeView {
protected override void OnHandleCreated(EventArgs e) {
SendMessage(this.Handle, TVM_SETEXTENDEDSTYLE, (IntPtr)TVS_EX_DOUBLEBUFFER, (IntPtr)TVS_EX_DOUBLEBUFFER);
base.OnHandleCreated(e);
}
// Pinvoke:
private const int TVM_SETEXTENDEDSTYLE = 0x1100 + 44;
private const int TVM_GETEXTENDEDSTYLE = 0x1100 + 45;
private const int TVS_EX_DOUBLEBUFFER = 0x0004;
[DllImport("user32.dll")]
private static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wp, IntPtr lp);
}
并非
绝对有必要为此派生一个新类,您还可以编写一个静态类函数,将控件传递给该函数以启用双缓冲:
public static class Helper
{
public static void EnableDoubleBuffering(Control control)
{
SendMessage(control.Handle, TVM_SETEXTENDEDSTYLE, (IntPtr)TVS_EX_DOUBLEBUFFER, (IntPtr)TVS_EX_DOUBLEBUFFER);
}
private const int TVM_SETEXTENDEDSTYLE = 0x1100 + 44;
private const int TVM_GETEXTENDEDSTYLE = 0x1100 + 45;
private const int TVS_EX_DOUBLEBUFFER = 0x0004;
[DllImport("user32.dll")]
private static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wp, IntPtr lp);
}
如果你像我一样是新手并且需要它 vb.net 这里是@Hans Passant 答案。我使用了它,变化是显着的
Protected Overrides Sub OnHandleCreated(ByVal e As EventArgs)
SendMessage(Me.Handle, TVM_SETEXTENDEDSTYLE, CType(TVS_EX_DOUBLEBUFFER, IntPtr), CType(TVS_EX_DOUBLEBUFFER, IntPtr))
MyBase.OnHandleCreated(e)
End Sub
Private Const TVM_SETEXTENDEDSTYLE As Integer = &H1100 + 44
Private Const TVM_GETEXTENDEDSTYLE As Integer = &H1100 + 45
Private Const TVS_EX_DOUBLEBUFFER As Integer = &H4
<DllImport("user32.dll")>
Private Shared Function SendMessage(ByVal hWnd As IntPtr, ByVal msg As Integer, ByVal wp As IntPtr, ByVal lp As IntPtr) As IntPtr
End Function