繁体   English   中英

Treeview 闪烁?

[英]Treeview flickering?

I came to know that by adding TreeView.BeginUpdate will prevent flickering of treeview, but when i added it in to my project all nodes of my treeview disappears, Can any body tell me why it happens, here is the code snippet where i used 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 循环中,将它们移到外面以立即改进,您使情况变得更糟。

这可能足以解决您的问题。 但是你可以做得更好,抑制闪烁需要双缓冲。 .NET TreeView 类覆盖 DoubleBuffered 属性并将其隐藏 这是一个历史意外,原生 Windows 控件仅在 Windows XP 及更高版本中支持双缓冲。 .NET 曾经支持 Windows 2000 和 Windows 98。

如今,这不再完全相关。 您可以通过从 TreeView 派生自己的类来将其放回原处。 向您的项目添加一个新类并粘贴如下所示的代码。 编译。 将新控件从工具箱顶部拖放到窗体上,替换现有的 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);
}

如果你像我一样是新手并且在 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

It is not absolutely necessary to derive a new class for this, you can also write a static class function to which you pass the control to enable the doublebuffering:

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);
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM