我实际上有一个类似于TreeView的自定义UserControl。它唯一缺少的是来自TreeView的CollapseAll()
方法,因此我要求a)找到CollapseAll方法的源代码,以便我可以复制它,或者b)手动(并递归地)遍历所选节点的所有子节点并折叠它们。
这是我当前的崩溃方法:
private void OnNodeCollapsed(TreeNode node) {
foreach(FileSystemNode n in node.Nodes) {
if(n.NodeType != FileSystemNodeType.Computer && n.NodeType != FileSystemNodeType.Drive) {
if(n.Nodes.Count > 0) {
n.Nodes.Clear();
}
}
}
foreach(TreeNode child in node.Nodes) {
// and this is where I lose it
}
}
我只想折叠子节点,而不是整个树。有没有办法做到这一点?
这是一个很好的解决方案:Recursion with yield return elements order in tree。
答案 0 :(得分:2)
您可以为自定义控件添加这样的扩展名,并使用以下展开/折叠方法
public static class TreeViewExt
{
public static void ExpandRecursively(this ItemsControl itemsControl, bool expand, int levelDepth)
{
int depth = levelDepth == int.MaxValue ? levelDepth : levelDepth - 1;
TreeViewItem treeViewItem = itemsControl as TreeViewItem;
if (treeViewItem != null)
treeViewItem.IsExpanded = expand || levelDepth >= 0; // expand, or keep expanded when levelDepth >= 0
if (levelDepth > 0 || !expand)
{
// get container generator of itemsControl
ItemContainerGenerator itemContainerGenerator = itemsControl.ItemContainerGenerator;
// if containers have already been generated, the subItems can be expanded/collapsed
if (itemContainerGenerator.Status == GeneratorStatus.ContainersGenerated)
{
for (int i = itemsControl.Items.Count - 1; i >= 0; --i)
{
ItemsControl childControl = itemContainerGenerator.ContainerFromIndex(i) as ItemsControl;
if (childControl != null)
childControl.ExpandRecursively(expand, depth);
}
}
else
{
EventHandler handler = null; // store in variable, so the handler can be detached
handler = new EventHandler((s, e) =>
{
if (itemContainerGenerator.Status == GeneratorStatus.ContainersGenerated)
{
for (int i = itemsControl.Items.Count - 1; i >= 0; --i)
{
ItemsControl childControl = itemContainerGenerator.ContainerFromIndex(i) as ItemsControl;
if (childControl != null)
childControl.ExpandRecursively(expand, depth);
itemContainerGenerator.StatusChanged -= handler; // detach
}
}
});
itemContainerGenerator.StatusChanged += handler; // attach
}
}
}
}
完整代码:Treeview Recursive Expand/Collapse
修改强>
由于OP想要为WinForm UserControl执行此操作,您可以使用这样的方法遍历子控件,
private IEnumerable<Node> getAllNodesRecursively(Node subnode)
{
// Return the parent before its children
yield return subnode;
foreach (Node node in subnode.Nodes)
{
foreach(Node n in getAllNodesRecursively(node))
{
yield return n;
}
}
}