簡體   English   中英

從父節點刪除子節點

[英]Remove Child Nodes from Parent Node

您好,我目前有一個具有以下結構的TreeView

  • 兒童

      • 兒童
        • 兒童
        • 兒童
          • 根N
          • 兒童N

    TreeView結構基本上可以具有NRootNodes-NChildren ,而NRootNodes可以具有NRoots和NChildren,因此基本上就像Windows資源管理器窗口一樣。

我當前遇到的問題是,我必須獲取所有的Parents或Root,在本例中為Roots / RootN ,然后必須刪除其所有子節點,在本例中為Child / ChildN 最后,我只需要具有父節點,然后對其進行克隆,以便可以將其移動到TreeView中的其他位置。

根節點具有唯一的標記- 文件夾 ,子節點具有另一個獨特的標記- 計算 ,正如我之前所說的,我必須擺脫選定節點中的所有計算,以便僅保留該選定節點的結構。

基本上,最后我必須有這樣的東西:

我有一個遞歸方法,可以“掃描” SelectedNode並獲取所有的Parents:

public  List<TreeNode> CollectParentNodes(TreeNodeCollection parentCollection, List<TreeNode> collectedNodes)
    {

        foreach (TreeNode node in parentCollection)
        {
            if (!collectedNodes.Contains(node.Parent))
            {
                collectedNodes.Add(node.Parent);
                parentNodeAdded = true;
            }

            if (node.Level != 0 && node.Tag.ToString() != Enumerations.NodeType.Calculation.ToString())
                collectedNodes.Add(node);

            if (node.Nodes.Count > 0)
                CollectParentNodes(node.Nodes, collectedNodes);
        }
        parentNodeAdded = false;
        return collectedNodes;
    }

最后,我有一個可以容納所有父代的列表,但我面臨的問題是父代也包含其后代,在這種情況下, 計算方式

我已經搜索過Google和StackOverFlow,但找不到任何幫助,如果已經解決,我會提前致以歉意。

謝謝。

您可以為TreeView創建一個擴展方法GetAllNodes,該方法返回List

記住using System.Linq; 在代碼頂部

public static class Extensions
{
    public static List<TreeNode> GetAllNodes(this TreeView tree)
    {
        var firstLevelNodes = tree.Nodes.Cast<TreeNode>();
        return firstLevelNodes.SelectMany(x => GetNodes(x)).Concat(firstLevelNodes).ToList();
    }

    private static IEnumerable<TreeNode> GetNodes(TreeNode node)
    {
        var nodes = node.Nodes.Cast<TreeNode>();
        return nodes.SelectMany(x => GetNodes(x)).Concat(nodes);
    }
}

用法將是:

var result = this.treeView1.GetAllNodes().Where(x => x.Tag == "FOLDER").ToList();

請記住,無論您想在哪里使用擴展類的名稱空間,都應在代碼頂部添加它。

例如,您可以將所有帶有Folder標簽的節點設置為紅色前色:

var result = this.treeView1.GetAllNodes().Where(x => (x.Tag as string) == "FOLDER").ToList();
result.ForEach(x => x.ForeColor = Color.Red);

這是截圖

在此處輸入圖片說明

這將創建一個新樹,其中所選節點為根,並且其子節點僅由標記為“文件夾”的節點組成。
您需要創建一個復制構造函數(或擴展方法)來深度復制節點,以防止對節點對象的操作影響原始樹源:

public TreeNode CollectFolderChildNodes(TreeNode selectedNode)
{
   if (selectedNode.Tag == "Calculation")
      return null;

   // Get all the children that are tagged as folder
   var childRootNodes = selectedNode.Children.Where((childNode) => childNode.Tag == "Folder";

   // Clone root node using a copy constructor
   var newRoot = new TreeNode(selectedNode);    
   newRoot.Children.Clear();

   foreach (var childNode in childRootNodes)
   { 
      // Iterate over all children and add them to the new tree
      if (childNode.Children.Any())
      {       
         // Repeat steps for the children of the current child. 
         // Recursion stops when the leaf is reached                    
         newRoot.Children.Add(CollectFolderChildNodes(childNode));             
      }     
      else
      {
        // The current child item is leaf (no children)
        newRoot.Children.Add(new TreeNode(childNode)); 
      }     
   }

   return newRoot;
}

我認為應該這樣做,但是我沒有對其進行測試。 但也許至少背后的想法很明確。

但是,正如我之前提到的,最好遍歷樹(使用相同的ItemsSource )並將屬性(例如IsHidingCalculations )設置為true以便僅顯示文件夾。 IsHidingCalculations評估為true時,您將需要實現ItemsStyle並使用觸發器將項目VisibilityCollapsed

要克隆沒有子節點的節點,可以創建如下擴展方法:

public static TreeNode CloneWithoutChildren(this TreeNode node)
{
    return new TreeNode(node.Text, node.ImageIndex, node.SelectedImageIndex)
    {
         Name = node.Name,
         ToolTipText = node.ToolTipText,
         Tag = node.Tag,
         Checked = node.Checked
    }
}

接着:

collectedNodes.Add(node.CloneWithoutChildren());

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM