[英]Remove Child Nodes from Parent Node
您好,我目前有一個具有以下結構的TreeView
:
兒童
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
並使用觸發器將項目Visibility
為Collapsed
。
要克隆沒有子節點的節點,可以創建如下擴展方法:
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.