【问题标题】:TreeView - Iterate through all nodes, stop at first visibleTreeView - 遍历所有节点,在第一次可见时停止
【发布时间】:2018-12-27 14:45:37
【问题描述】:

我现在有精神障碍,这不会那么难。

我有一个函数应该获取 TreeView 中最后一个可见节点。首先,我想转到第一个可见节点,然后只要 node.IsVisible() 从那里开始第二个。

这是我所拥有的:

public TreeNode GetLastVisibleNode()
    {
        var node = treeControl1.Nodes.Cast<TreeNode>().Where(x => x.IsVisible).FirstOrDefault();
        TreeNode retVal = node;
        while (node != null && node.IsVisible)
        {
            if (!node.IsSelected)
                retVal = node;
            node = node.NextVisibleNode;
        }
        return retVal;
    }

如您所见,当我有第一个可见节点(万岁)时,我让它迭代到最后一个可见节点,但我获得第一个可见节点的方法是错误的(OHHHHH!)

我注意到 treeControl1.Nodes 只给了我父节点但显然我想获得所有节点的第一个可见节点。

我也知道我可能需要一个递归方法,但正如我一开始所说,我现在有一个心理障碍,想尽快解决这个问题:(

【问题讨论】:

  • 你所说的 first 是什么意思 - 最左边的节点,最底部的节点或集合中的第一个节点(这似乎是你目前正在做的事情)?
  • 我的 TreeView - 视图中可见的第一个节点。使用我在函数中的第一行,它可以获取第一个可见的父节点(因为 TreeView.Nodes 只返回一个节点列表,它也可以有一个节点列表,可以......)但如果它是一个孩子,它也应该工作父母的孩子的孩子的孩子。

标签: c# loops recursion treeview iteration


【解决方案1】:

这应该可以解决你的问题:

public TreeNode GetLastVisibleNode ()
{
    var node = treeControl1.Nodes.Cast <TreeNode> ().Select (GetFirstVisibleNode).
                            FirstOrDefault (first => first != null);

    var retVal = node;
    while (node != null && node.IsVisible)
    {
        if (!node.IsSelected)
            retVal = node;
        node = node.NextVisibleNode;
    }

    return retVal;


    TreeNode GetFirstVisibleNode (TreeNode parentNode) =>
        parentNode.IsVisible
            ? parentNode
            : parentNode.Nodes.Cast <TreeNode> ().Select (GetFirstVisibleNode).
                         FirstOrDefault (childFirstNode => childFirstNode != null);
}

但是,我看不出您到底想达到什么目的。如果此解决方案不适合您,您应该尝试更好地表达您的问题。

实际上,您似乎可以通过直接接收 last 可见节点来解决您的问题:

public TreeNode GetLastVisibleNode ()
{
    return treeControl1.Nodes.Cast <TreeNode> ().Select (GetLastVisibleNode).
                            LastOrDefault (first => first != null);


    TreeNode GetLastVisibleNode (TreeNode parentNode) =>
        parentNode.IsVisible
            ? parentNode
            : parentNode.Nodes.Cast <TreeNode> ().Select (GetLastVisibleNode).
                         LastOrDefault(childFirstNode => childFirstNode != null);
}

由于缺乏工作环境,我无法对此进行测试,但它实际上应该这样做。


好的,我想我应该稍微解释一下我的代码。 这部分:

TreeNode GetFirstVisibleNode (TreeNode parentNode) =>
        parentNode.IsVisible
            ? parentNode
            : parentNode.Nodes.Cast <TreeNode> ().Select (GetFirstVisibleNode).
                         FirstOrDefault (childFirstNode => childFirstNode != null);

其实和这个是一样的:

TreeNode GetFirstVisibleNode (TreeNode parentNode)
{
    if (parentNode.IsVisible)
        return parentNode;
    foreach (var childNode in parentNode.Nodes.Cast <TreeNode> ())
    {
        var childFirstNode = GetFirstVisibleNode (childNode);
        if (childFirstNode != null)
            return childFirstNode;
    }

    return null;
}

第一个 Linq 查询是类似的。

return 语句后面的部分没有错——它被称为局部函数。你当然可以把它放在函数之外,但是因为你永远不需要它,而不是GetLastVisibleNode(),你可以把它放在里面。 Here你可以阅读更多。

【讨论】:

  • 这正是我想要的,但我不知道你在那里做了什么:D 可能是因为我到目前为止只使用过 Java,但我现在正在实习,我必须编写代码在 C# 中,所以 LINQ 语句对我来说是全新的(我在现有代码中找到了另一个)。但也许你必须编辑你提供的代码并将第二部分放在函数之外,因为它在返回之后
【解决方案2】:

我发现 TreeView.TopNode 为我提供了第一个可见节点。

从那里开始,只要 node.IsVisible 和 node != null,我就遍历列表。

public TreeNode GetLastVisibleNode()
{
    TreeNode node = treeControl1.TopNode;
    TreeNode retVal;
    do
    {
        retVal = node;
        node = node.NextVisibleNode;
    } while (node != null && node.IsVisible);

    return retVal;
}

【讨论】:

    猜你喜欢
    • 2010-10-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-01
    相关资源
    最近更新 更多