使用所有节点和子节点过滤 TreeView [英] Filter TreeView with all nodes and childs
问题描述
我有一个父节点,它有一个子节点,这个子节点还有另一个子节点等等,它们都在一个 TreeView
I have a parent node which has a child, and this child has another child etc.. and they are all in a TreeView
所以我创建了一个全局变量来将我的所有节点保存为:
So I create a global variable to save all my nodes as:
private TreeNodeCollection ProjectTreeView { get; set; }
然后我将树节点的数据设置到我的全局变量中:
Then I set data of the tree node into my global variable:
ProjectTreeView = this.tvProjectList.Nodes[0].Nodes;
当我点击一个按钮时,我想过滤我的 TreeView,所以首先我清除 TreeView,然后遍历集合并只显示满足我的条件的节点:
And When I click a button I want to filter my TreeView, so first I clear the TreeView, then I iterate over the collection and only show the nodes that meet my condition:
private void rdoIssued_Click(object sender, EventArgs e)
{
//blocks repainting tree till all objects loaded
this.tvProjectList.BeginUpdate();
this.tvProjectList.Nodes.Clear();
foreach (TreeNode projectNode in ProjectTreeView)
{
if (bool.Parse(projectNode.Tag.ToString().Split('|')[8]) == true)
{
this.tvProjectList.Nodes.Add((TreeNode)projectNode.Clone());
}
}
//enables redrawing tree after all objects have been added
this.tvProjectList.EndUpdate();
}
问题是它只克隆第一个节点而不是子节点.如何克隆具有所有子节点的节点?
The problem is it only clone the first Node but not the children. How can I clone a node with all children?
推荐答案
做相反的事情要容易得多.您可以遍历所有节点以保留过滤的节点并删除其余节点.首先,为0级节点创建一个备份.
Doing the opposite is much easier. You could iterate through all the nodes to keep the filtered nodes and remove the rest. First, create a backup for the 0-level nodes.
public partial class YourForm : Form
{
public YourForm()
{
InitializeComponent();
//...
BackUpTree();
}
private List<TreeNode> ProjectTreeView = new List<TreeNode>();
private void BackUpTree()
{
if (ProjectTreeView.Count == 0)
foreach (TreeNode tn in tvProjectList.Nodes)
ProjectTreeView.Add(tn.Clone() as TreeNode);
}
创建一个重置原始树的方法:
Create a method to reset the original tree:
private void ResetTree(bool expandAll = false)
{
tvProjectList.BeginUpdate();
tvProjectList.Nodes.Clear();
foreach (var tn in ProjectTreeView)
tvProjectList.Nodes.Add(tn.Clone() as TreeNode);
if (expandAll) tvProjectList.ExpandAll();
tvProjectList.EndUpdate();
}
获取所有节点的迭代器函数:
Iterator function to get all the nodes:
private IEnumerable<TreeNode> GetAllNodes(TreeNodeCollection Nodes)
{
foreach (TreeNode tn in Nodes)
{
yield return tn;
foreach (TreeNode child in GetAllNodes(tn.Nodes))
yield return child;
}
}
... 以及执行过滤器部分的方法:
... and a method to do the filter part:
private void FilterTree(bool expandAll = false)
{
ResetTree(); // <- comment if you are doing multiple filters...
tvProjectList.BeginUpdate();
//.Reverse() is required here to iterate backward because the collections
//are modified when removing nodes. You can call .ToList() instead to
//iterate forward.
foreach (var node in GetAllNodes(tvProjectList.Nodes).Reverse())
{
if (bool.Parse(projectNode.Tag.ToString().Split('|')[8]) == false)
if (node.Parent is null)
tvProjectList.Nodes.Remove(node);
else
node.Parent.Nodes.Remove(node);
}
if (expandAll) tvProjectList.ExpandAll();
tvProjectList.EndUpdate();
}
}
这篇关于使用所有节点和子节点过滤 TreeView的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!