Merging Treenodes

前端 未结 4 1806
借酒劲吻你
借酒劲吻你 2021-01-19 03:41

Does anyone know of an algorithm that will merge treenodes in the following way?

treeA
   \\ child a
          \\node(abc)
   \\ child b
          \\node(xyz         


        
4条回答
  •  孤独总比滥情好
    2021-01-19 04:28

    If you are using the Node.Name attribute to set the actual path of the item, then a merge is somewhat simple.

    First, create a TreeNodeCollection extension like so (this is needed to have a Case Sensitive Find() method for the TreeNodeCollection, which ensures that the Unique Path can be unique by Case as well) :

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    
    namespace TreeViewApp
    {
        public static class TreeNodeCollectionExtensions
        {
            public static TreeNode[] FindExact(this TreeNodeCollection coll, string keytofind)
            {
                TreeNode[] retval;
    
                if (String.IsNullOrWhiteSpace(keytofind) || coll == null)
                {
                    retval = new TreeNode[0];
                }
                else
                {
                    TreeNode[] badfinds = coll.Find(keytofind, true);
    
                    List goodfinds = new List();
                    foreach (TreeNode bad in badfinds)
                    {
                        if (bad.Name == keytofind)
                            goodfinds.Add(bad);
                    }
                    retval = goodfinds.ToArray();
    
                }
                return retval;
            }
        }
    }
    

    Second, fill a treeview with your Source nodes...
    Thrid, fill a treeview with your Target nodes...
    Fourth, create an empty treeview.

    and then, it's as simple as this:

        private void btn_Merge_Click(object sender, EventArgs e)
        {
            //first merge
            foreach (TreeNode sourceNode in this.treeview_Source.Nodes)
            {
                FindOrAdd(sourceNode, ref this.treeview_Merged);
            }
    
            //second merge
            foreach (TreeNode targetNode in this.treeview_Target.Nodes)
            {
                FindOrAdd(targetNode, ref this.treeview_Merged);
            }
        }
    
        private void FindOrAdd(TreeNode FindMe, ref TreeView InHere)
        {
            TreeNode[] found = InHere.Nodes.FindExact(FindMe.Name);
            //if the node is not found, add it at the proper location.
            if (found.Length == 0)
            {
                if (FindMe.Parent != null)
                {
                    TreeNode[] foundParent = InHere.Nodes.FindExact(FindMe.Parent.Name);
                    if (foundParent.Length == 0)
                        InHere.Nodes.Add((TreeNode)FindMe.Clone());
                    else
                        foundParent[0].Nodes.Add((TreeNode)FindMe.Clone());
                }
                else
                    InHere.Nodes.Add((TreeNode)FindMe.Clone());
            }
            else
            {
                //if the item was found, check all children.
                foreach (TreeNode child in FindMe.Nodes)
                    FindOrAdd(child, ref InHere);
            }
        }
    

    Once again, this solution only works if you have unique paths... with the extension, it also accounts for uniqueness at the case level.

    I posted this here in the hopes of helping someone who, like me, had to search for a solution for days on end without success and had to build my own.

提交回复
热议问题