【问题标题】:TreeView Check/UnCheck all child itemsTreeView 选中/取消选中所有子项
【发布时间】:2013-01-19 21:10:28
【问题描述】:

如何在 TreeView 中选中/取消选中所有子项? 当其中一项变为选定状态并且子项已选中/未选中时,可能会发生错误。

Link to VS 2010 Project+Exe

Video on YOUTUBE

private void Form1_Load(object sender, EventArgs e)
    {
        treeView1.CheckBoxes = true;
        treeView1.BeginUpdate();
        treeView1.Nodes.Add("1111");
        treeView1.Nodes[0].Nodes.Add("2222");
        treeView1.Nodes[0].Nodes.Add("2222");
        treeView1.Nodes[0].Nodes.Add("2222");
        treeView1.Nodes[0].Nodes.Add("2222");
        treeView1.Nodes[0].Nodes[1].Nodes.Add("3333");
        treeView1.Nodes[0].Nodes[1].Nodes[0].Nodes.Add("4444");
        treeView1.Nodes[0].Nodes[1].Nodes[0].Nodes.Add("4444");
        treeView1.Nodes[0].Nodes[1].Nodes[0].Nodes.Add("4444");
        treeView1.EndUpdate();

        treeView1.ExpandAll();
    }

    private void treeView1_AfterCheck(object sender, TreeViewEventArgs e)
    {
        treeView1.BeginUpdate();

        foreach (TreeNode Node in e.Node.Nodes)
        {
            Node.Checked = e.Node.Checked;
        }

        treeView1.EndUpdate();
    }

【问题讨论】:

  • 什么?如果您需要检查所有子节点,请递归执行。
  • 安德烈你需要做一些递归调用例如public void UncheckAllNodes(TreeNodeCollection nodes) { foreach (TreeNode node in nodes) { node.Checked = false; CheckChildren(node, false); } }
  • 对于 CheckChildern(node,false) 执行此操作private void CheckChildren(TreeNode rootNode, bool isChecked) { foreach (TreeNode node in rootNode.Nodes) { CheckChildren(node, isChecked); node.Checked = isChecked; } }
  • @DJKRAZE:为什么不回答这个问题?

标签: c# treeview


【解决方案1】:

使用您在 Form_Load 中的代码保持该代码正常工作并在您的代码中添加这两种方法

private void Form1_Load(object sender, EventArgs e)
{
    treeView1.CheckBoxes = true;
    treeView1.BeginUpdate();
    treeView1.Nodes.Add("1111");
    treeView1.Nodes[0].Nodes.Add("2222");
    treeView1.Nodes[0].Nodes.Add("2222");
    treeView1.Nodes[0].Nodes.Add("2222");
    treeView1.Nodes[0].Nodes.Add("2222");
    treeView1.Nodes[0].Nodes[1].Nodes.Add("3333");
    treeView1.Nodes[0].Nodes[1].Nodes[0].Nodes.Add("4444");
    treeView1.Nodes[0].Nodes[1].Nodes[0].Nodes.Add("4444");
    treeView1.Nodes[0].Nodes[1].Nodes[0].Nodes.Add("4444");
    treeView1.EndUpdate();
    treeView1.ExpandAll();
}

private void treeView1_AfterCheck(object sender, TreeViewEventArgs e)
{
    foreach (TreeNode childNode in e.Node.Nodes)
    {
        childNode.Checked = e.Node.Checked;
    }
}

【讨论】:

  • DJ KRAZE 这无济于事。所以我制作视频来告诉你什么是错的。 youtube.com/watch?v=kviRgkpUiMs 我还修复了视频链接。
  • 我为您提供了一个更新的版本,我希望这可以解决您的问题,它也可以正常工作,这是一个更简洁的代码版本
【解决方案2】:

我想出的解决方案如下:

  • 为了执行我使用 Linq 的选择:

    if (e.Node.Nodes.Count > 0) e.Node.Nodes.Cast<TreeNode>().Where(tnc => tnc.Checked != e.Node.Checked).ForEach(tn => tn.Checked = e.Node.Checked);

  • 然后为了处理事件选择,我扩展了 TreeView 类: public class MyTV : TreeView { protected bool TopOfCascade; TreeNode startNode; public Action FinishedCheckEventsDelegate; public Action InitiateCascadeCheckEventsDelegate; public MyTV() : base() { TopOfCascade = false; startNode = null; } protected override void OnBeforeCheck(TreeViewCancelEventArgs e) { base.OnBeforeCheck(e); if (!TopOfCascade && !e.Cancel) { TopOfCascade = true; startNode = e.Node; if (InitiateCascadeCheckEventsDelegate != null) InitiateCascadeCheckEventsDelegate(); } } protected override void OnAfterCheck(TreeViewEventArgs e) { base.OnAfterCheck(e); if (startNode == e.Node && e.Action != TreeViewAction.Unknown) { if (FinishedCheckEventsDelegate != null) FinishedCheckEventsDelegate(); TopOfCascade = false; startNode = null; } } 在主机控件中,您可以挂钩前置和后置级联事件并遍历所有选中/未选中的树节点,以避免大量交叉事件触发。您可以通过某个容器控制级联。

我从以下网络实现中获得了 ForEach 到 IEnumerable:

public static void ForEach<T>(this IEnumerable<T> source, Action<T> action)
{
  if (source == null) throw new ArgumentNullException("source");
  if (action == null) throw new ArgumentNullException("action");
  foreach (T item in source)
  {
    action(item);
  }
}

祝你好运!

【讨论】:

    【解决方案3】:

    这是一个答案(来自 Hans Passant):

    Winforms treeview, recursively check child nodes problem

    我把它写成答案,而不是评论,以便更容易找到。

    【讨论】:

      【解决方案4】:
          private void treeView1_AfterCheck(object sender, TreeViewEventArgs e)
          {
      
              if (e.Action != TreeViewAction.Unknown)
              {
                  if (e.Node.Nodes.Count > 0)
                  {
                      /* Calls the CheckAllChildNodes method, passing in the current 
                      Checked value of the TreeNode whose checked state changed. */
                      this.CheckAllChildNodes(e.Node, e.Node.Checked);
                  }
      
              }
          }
      
         private void CheckAllChildNodes(TreeNode treeNode, bool nodeChecked)
          {
              foreach (TreeNode node in treeNode.Nodes)
              {
                  node.Checked = nodeChecked;
                  if (node.Nodes.Count > 0)
                  {
                      // If the current node has child nodes, call the CheckAllChildsNodes method recursively. 
                      this.CheckAllChildNodes(node, nodeChecked);
                  }
              }
          }
      

      【讨论】:

        【解决方案5】:
            private void CheckAllChildNodes(TreeNode treeNode, bool nodeChecked)
            {
                foreach (TreeNode node in treeNode.Nodes)
                {
                    node.Checked = nodeChecked;
                    if (node.Nodes.Count > 0)
                    {
                        this.CheckAllChildNodes(node, nodeChecked);
                    }
                }
            }
            private void treeView_AfterCheck(object sender, TreeViewEventArgs e)
            {
                if (e.Action != TreeViewAction.Unknown)
                {
                    if (e.Node.Nodes.Count > 0)
                    {
                        if (!e.Node.Checked)
                        {
                            this.CheckAllChildNodes(e.Node, e.Node.Checked);
                        }
                    }
                }
        
                if (e.Node.Parent != null)
                {
                    TreeNode n = e.Node;
                    while (n.Parent != null)
                    {
                        if (n.Checked)
                        {
                            n.Parent.Checked = true;
                        }
                        n = n.Parent;
                    }
                }
        
            }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2018-10-14
          • 1970-01-01
          • 1970-01-01
          • 2012-06-16
          • 1970-01-01
          • 2011-07-10
          • 2022-11-11
          相关资源
          最近更新 更多