从 Parent 个节点中删除 Child 个节点
Remove Child Nodes from Parent Node
你好,我目前有一个 TreeView
结构如下:
- 根目录
Child
- 根目录
- Child
- 根目录
- Child
- Child
- RootN
- ChildN
TreeView 结构基本上可以有 NRootNodes - NChildren 并且 NRootNodes 可以有 NRoots 和 NChildren 所以基本上就像 Windows Explorer Window.
我目前的问题是我必须获得所有 Parents 或 Root,在本例中为 Roots / RootN 然后我必须删除他们所有的 Child 节点,在这种情况下 Child / ChildN 。最后,我只需要 Parent 个节点,然后克隆它们,这样我就可以将它们移动到 TreeView 中的不同位置。
RootNodes 有一个独特的标签 - Folder 和 ChildNodes 有另一个独特的标签 - Calculations,正如我所说早些时候,我必须摆脱选定节点中的所有计算,因此只保留该选定节点的结构。
基本上最后我必须有这样的东西:
- 根目录
- 根目录
- 根目录
- 根目录
- 根目录
我有一个递归方法 "scans" 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;
}
最后我有一个包含所有 Parent 的列表,但我面临的问题是 Parent 也包含它们的后代,在这种情况下 计算
我搜索了 Google 和 Whosebug,但找不到任何帮助,如果已经有人回答,我提前表示歉意。
谢谢。
要克隆没有子节点的节点,您可以像这样创建一个扩展方法:
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());
您可以为 return List
的 TreeView 创建扩展方法 GetAllNodes
记得在代码顶部使用 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();
请记住在代码顶部的任何要使用的地方添加扩展的命名空间 class。
例如,您可以将带有文件夹标签的所有节点设置为红色前景色:
var result = this.treeView1.GetAllNodes().Where(x => (x.Tag as string) == "FOLDER").ToList();
result.ForEach(x => x.ForeColor = Color.Red);
这是截图
这将创建一个新树,将所选节点作为根节点,其子节点仅包含标记为 "Folder" 的节点。
您需要创建一个复制构造函数(或扩展方法)来深度复制节点,以防止对节点对象的操作影响您的原始树源:
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 计算结果为真时,您需要实施 ItemsStyle
并使用将项目 Visibility
设置为 Collapsed
的触发器。
你好,我目前有一个 TreeView
结构如下:
- 根目录
Child
- 根目录
- Child
- 根目录
- Child
- Child
- RootN
- ChildN
- Child
TreeView 结构基本上可以有 NRootNodes - NChildren 并且 NRootNodes 可以有 NRoots 和 NChildren 所以基本上就像 Windows Explorer Window.
- 根目录
我目前的问题是我必须获得所有 Parents 或 Root,在本例中为 Roots / RootN 然后我必须删除他们所有的 Child 节点,在这种情况下 Child / ChildN 。最后,我只需要 Parent 个节点,然后克隆它们,这样我就可以将它们移动到 TreeView 中的不同位置。
RootNodes 有一个独特的标签 - Folder 和 ChildNodes 有另一个独特的标签 - Calculations,正如我所说早些时候,我必须摆脱选定节点中的所有计算,因此只保留该选定节点的结构。
基本上最后我必须有这样的东西:
- 根目录
- 根目录
- 根目录
- 根目录
- 根目录
- 根目录
- 根目录
- 根目录
我有一个递归方法 "scans" 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;
}
最后我有一个包含所有 Parent 的列表,但我面临的问题是 Parent 也包含它们的后代,在这种情况下 计算
我搜索了 Google 和 Whosebug,但找不到任何帮助,如果已经有人回答,我提前表示歉意。
谢谢。
要克隆没有子节点的节点,您可以像这样创建一个扩展方法:
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());
您可以为 return List
的 TreeView 创建扩展方法 GetAllNodes记得在代码顶部使用 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();
请记住在代码顶部的任何要使用的地方添加扩展的命名空间 class。
例如,您可以将带有文件夹标签的所有节点设置为红色前景色:
var result = this.treeView1.GetAllNodes().Where(x => (x.Tag as string) == "FOLDER").ToList();
result.ForEach(x => x.ForeColor = Color.Red);
这是截图
这将创建一个新树,将所选节点作为根节点,其子节点仅包含标记为 "Folder" 的节点。
您需要创建一个复制构造函数(或扩展方法)来深度复制节点,以防止对节点对象的操作影响您的原始树源:
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 计算结果为真时,您需要实施 ItemsStyle
并使用将项目 Visibility
设置为 Collapsed
的触发器。