Treeview闪烁?

vet*_*ori 19 c# treeview winforms

我开始知道通过添加TreeView.BeginUpdate可以防止树视图的闪烁,但是当我将它添加到我的项目中时,我的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);
Run Code Online (Sandbox Code Playgroud)

Han*_*ant 68

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);
}
Run Code Online (Sandbox Code Playgroud)

  • MSDN建议您使用TVM_SETEXTENDEDSTYLE并不完全正确; 根据http://msdn.microsoft.com/en-us/library/windows/desktop/bb773744(v=vs.85).aspx,WPARAM是一个掩码,LPARAM是标志.因此,跳过获取旧样式并执行SendMessage(this.Handle,TVM_SETEXTENDEDSTYLE,(IntPtr)TVS_EX_DOUBLEBUFFER,(IntPtr)TVS_EX_DOUBLEBUFFER); (5认同)
  • 呃,确实如此。我正在使用 MSDN 库的旧副本,其中记录了此错误。感谢您的正确! (2认同)