【问题标题】:TreeView is randomly failing to show newly added nodesTreeView 随机无法显示新添加的节点
【发布时间】:2012-07-02 10:33:47
【问题描述】:

我在 WinForm 应用程序中有一个TreeView,我正在使用addreorderdelete 方法来添加新节点、重新排序现有节点和删除旧注释。

有时当我添加一个新项目时,它会立即在TreeView 中显示,但是当我添加下一个节点时它确实正确显示。这似乎是随机发生的,因此很难找到根本原因。

即使节点没有在 UI 中正确显示,节点计数也是正确的。

TreeView1.BeginUpdate();
TreeView1.Nodes.Add("P1", "Parent");

foreach(User u in items)
{
    if( condition)
    {
        node.Text =u.sNodeText; 
        node.Tag = u;
        node.Text = u.sNodeText;                    
        GetChildren(node);
        TreeView1.Nodes["P1"].Nodes.Add((TreeNode)node.Clone());
    }
}            
TreeView1.ExpandAll();
TreeView1.EndUpdate();           
TreeView1.Refresh(); 

谁能回答这个问题?我认为这个问题并非毫无意义。 这是 GetChildren 方法。

     private void GetChildren(TreeNode node)
    {
        TreeNode Node = null;
        User nodeCat = (User)node.Tag;

        foreach (User  cat in items)
        {
            if (cat.sParentID == nodeCat.sID)
            {
                Node = node.Nodes.Add(cat.sNodeText);
                Node.Tag = cat;
                GetChildren(Node);
            }
        }

【问题讨论】:

  • 反对者:解释为什么这个问题不好会更有帮助。
  • 能否请您向我们展示GetChildren 方法的代码,以便我们重现这种奇怪的行为并提供解决方案。 @tenfour 这个问题很糟糕,因为它非常主观并且没有复制示例。顺便说一句,我没有投反对票。

标签: c# windows winforms treeview


【解决方案1】:

您是否尝试过 Invalidate()Refresh()? Refresh 只重绘客户端区域,而 Invalidate 重绘整个控件。这只是在黑暗中的一个镜头......我以前从未遇到过这个问题。

【讨论】:

    【解决方案2】:

    首先,调用GetChildren 方法后,为什么还要将节点添加到树中?如果它的 parentID 为空(或 null 或 0,取决于它的类型),你应该只将它添加到树中。 此外,将EnsureVisible 方法添加到新添加的节点,并删除克隆:

    ...
        if (u.sParentID==null)
        {
        TreeView1.Nodes["P1"].Nodes.Add(node); 
        node.EnsureVisible();
        }
    ...
    

    希望对你有帮助

    【讨论】:

      【解决方案3】:

      如果我没记错的话是不是有一个

      TreeView1.BeginUpdate() method that you could use and at the end utilize the 
      TreeView1.EndUpdate();
      

      【讨论】:

        【解决方案4】:

        我认为这可能与使用克隆有关,它会产生浅拷贝。由于使用了 Add 方法,节点计数会更新,但“新”节点仍然具有创建它的节点的引用,因此它不是唯一对象。尝试创建一个深层副本,看看效果如何。

        例如:

        public TreeNode DeepNodeClone(TreeNode src)
        {
        MemoryStream ms = new MemoryStream();
        BinaryFormatter bf = new BinaryFormatter();
        bf.Serialize(ms, src);
        ms.Position = 0;
        object obj = bf.Deserialize(ms);
        ms.Close();
        return (TreeNode)obj;
        }
        

        然后将此节点作为子节点添加到所需的父节点。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-07-10
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多