WinForms TreeView展开/折叠随机不起作用

时间:2019-01-17 17:57:14

标签: c# winforms treeview

我有一个其中包含TreeView的UserControl。我使用ImageList在每个节点上显示图标。我在使+/-按钮展开/折叠以始终正常工作时遇到一些困难。

您可以开始折叠或展开节点,它可以正常工作,但是最终您将到达一个节点,该节点不执行任何操作。如果您到达这些节点之一,并且多次单击而在两次单击之间存在一定的延迟(足够不被注册为双击),则它们将永远不会执行展开/折叠。但是,如果双击,则它们将正常工作。而且,似乎如果您扩展/折叠另一个节点,然后回到问题节点,它就可以正常工作。我想说一下,大约70%的节点在+/-上单击即可扩展/折叠,其余30%则需要双击或转到另一个节点,然后再返回。

我注意到如果删除了ImageList,似乎没有问题。我还注意到,如果我有一个TreeView直接添加到窗体,它似乎没有问题。几乎就像在某种程度上与使用ImageList的UserControl中具有TreeView有关,但这似乎很奇怪。

我整理了一个演示问题的小演示。这是UserControl:

partial class NavigationTree
{
    /// <summary> 
    /// Required designer variable.
    /// </summary>
    private System.ComponentModel.IContainer components = null;

    /// <summary> 
    /// Clean up any resources being used.
    /// </summary>
    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
    protected override void Dispose(bool disposing)
    {
        if (disposing && (components != null))
        {
            components.Dispose();
        }
        base.Dispose(disposing);
    }

    #region Component Designer generated code

    /// <summary> 
    /// Required method for Designer support - do not modify 
    /// the contents of this method with the code editor.
    /// </summary>
    private void InitializeComponent()
    {
        this.components = new System.ComponentModel.Container();
        System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(NavigationTree));
        this.Tree = new System.Windows.Forms.TreeView();
        this.ImageList = new System.Windows.Forms.ImageList(this.components);
        this.SuspendLayout();
        // 
        // Tree
        // 
        this.Tree.Dock = System.Windows.Forms.DockStyle.Fill;
        this.Tree.ImageIndex = 0;
        this.Tree.ImageList = this.ImageList;
        this.Tree.Location = new System.Drawing.Point(0, 0);
        this.Tree.Name = "Tree";
        this.Tree.SelectedImageIndex = 0;
        this.Tree.Size = new System.Drawing.Size(326, 448);
        this.Tree.TabIndex = 0;
        // 
        // ImageList
        // 
        this.ImageList.ImageStream = ((System.Windows.Forms.ImageListStreamer)(resources.GetObject("ImageList.ImageStream")));
        this.ImageList.TransparentColor = System.Drawing.Color.Transparent;
        this.ImageList.Images.SetKeyName(0, "Default");
        this.ImageList.Images.SetKeyName(1, "Down");
        this.ImageList.Images.SetKeyName(2, "Up");
        // 
        // NavigationTree
        // 
        this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
        this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
        this.Controls.Add(this.Tree);
        this.Name = "NavigationTree";
        this.Size = new System.Drawing.Size(326, 448);
        this.ResumeLayout(false);

    }

    #endregion

    private System.Windows.Forms.TreeView Tree;
    private System.Windows.Forms.ImageList ImageList;
}

生成节点的代码:

public partial class NavigationTree : UserControl
{
    public NavigationTree()
    {
        InitializeComponent();
    }

    private void BuildTree(
        int numberOfNodes,
        int level,
        TreeNodeCollection nodes)
    {
        if (level > 5)
        {
            return;
        }

        Enumerable.Range(0, numberOfNodes)
            .ToList()
            .ForEach(index =>
            {
                var node = new TreeNode($"Level {level}, index {index}");
                nodes.Add(node);
                BuildTree(3, level + 1, node.Nodes);
            });
    }

    public void UpdateTree()
    {
        BuildTree(3, 1, Tree.Nodes);
        Tree.ExpandAll();
    }
}

三个ImageList图标只是3个16x16 png文件。表单也很简单...

partial class Form1
{
    /// <summary>
    /// Required designer variable.
    /// </summary>
    private System.ComponentModel.IContainer components = null;

    /// <summary>
    /// Clean up any resources being used.
    /// </summary>
    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
    protected override void Dispose(bool disposing)
    {
        if (disposing && (components != null))
        {
            components.Dispose();
        }
        base.Dispose(disposing);
    }

    #region Windows Form Designer generated code

    /// <summary>
    /// Required method for Designer support - do not modify
    /// the contents of this method with the code editor.
    /// </summary>
    private void InitializeComponent()
    {
        this.Tree = new TestTreeViewIconExpandCollapse.NavigationTree();
        this.SuspendLayout();
        // 
        // Tree
        // 
        this.Tree.Dock = System.Windows.Forms.DockStyle.Fill;
        this.Tree.Location = new System.Drawing.Point(0, 0);
        this.Tree.Name = "Tree";
        this.Tree.Size = new System.Drawing.Size(605, 499);
        this.Tree.TabIndex = 0;
        // 
        // Form1
        // 
        this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
        this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
        this.ClientSize = new System.Drawing.Size(605, 499);
        this.Controls.Add(this.Tree);
        this.Name = "Form1";
        this.Text = "Form1";
        this.ResumeLayout(false);

    }

    #endregion
    private NavigationTree Tree;
}

然后...

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    protected override void OnLoad(
        EventArgs e)
    {
        base.OnLoad(e);
        Tree.UpdateTree();
    }
}

此示例在以下位置进行了测试:

Windows 10 Pro(10.0.17134) Visual Studio企业版2017 15.9.5 .NET 3.5和4.72均经过测试。

如果我在TreeView上将ImageList设置为none,则似乎工作正常。我试图研究这是否是一个已知问题,但找不到任何东西。我怀疑我可以添加一些鼠标单击代码以使其始终如一地工作,但我宁愿不要这样做。

0 个答案:

没有答案