【问题标题】:auto check child nodes when parent node is checked检查父节点时自动检查子节点
【发布时间】:2013-08-25 05:38:50
【问题描述】:

我在 VS 2012 中使用 .net c# 并尝试编写一个函数来自动检查已检查父树视图节点的所有子节点。我是 c# 编程新手,所以我找到了以下代码,但它有两个问题:

  1. if (HasChildNodes(node)) Visual Studio 报告 HasChildNodes 的行未知。
  2. 我想从单击检查的选定节点开始,我认为代码遍历整个树?

感谢您的帮助。

        treeView.BeginUpdate();
        //Loop through all the nodes of tree
        foreach (TreeNode node in treeView.Nodes)
        {
            //If node has child nodes
            if (HasChildNodes(node))
            {
                if (node.Checked == true)
                {
                    //Check all the child nodes.
                    foreach (TreeNode childNode in node.Nodes)
                    {
                        childNode.Checked = true;
                    }
                }
            }
        }
        treeView.EndUpdate();

【问题讨论】:

    标签: c# .net visual-studio-2012


    【解决方案1】:

    下面是带有选中和取消选中子节点和父节点的树视图示例的工作代码(添加树视图并将名称指定为 tvwDynamic)

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    

    命名空间树形视图 { 公共部分类Form1:表格 { 公共表格1() { 初始化组件(); }

        private void Form1_Load(object sender, EventArgs e)
        {
            TreeNode MainNode = new TreeNode("Java");
            tvwDynamic.Nodes.Add(MainNode);
            MainNode = new TreeNode("PHP");
            tvwDynamic.Nodes.Add(MainNode);           
            TreeNode node2 = new TreeNode("C#");
            TreeNode node3 = new TreeNode("VB.NET");
            TreeNode[] childNodes = new TreeNode[] {node2,node3};
            MainNode = new TreeNode("ASP.NET", childNodes);
            tvwDynamic.Nodes.Add(MainNode);
             TreeNode node4 = new TreeNode("Winforms");
            TreeNode node5 = new TreeNode("Webforms");
              TreeNode[] SubchildNodes = new TreeNode[] {node4,node5};
            MainNode =  new TreeNode("Test",SubchildNodes);
            tvwDynamic.Nodes[2].Nodes[1].Nodes.Add(MainNode);
            tvwDynamic.CheckBoxes = true;
    
        }
    
        private void tvwDynamic_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);
    
                }
    
            }
    
            SelectParents(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);
    
                }
    
            }
    
        }
    
    
        private void SelectParents(TreeNode node, Boolean isChecked)
        {
            var parent = node.Parent;
    
            if (parent == null)
                return;
    
            if (!isChecked && HasCheckedNode(parent))
                return;
    
            parent.Checked = isChecked;
            SelectParents(parent, isChecked);
        }
    
        private bool HasCheckedNode(TreeNode node)
        {
            return node.Nodes.Cast<TreeNode>().Any(n => n.Checked);
        }
    } }
    

    【讨论】:

      【解决方案2】:
       treeview1.BeginUpdate();
       foreach (TreeNode tn in e.Node.Nodes)
           tn.Checked = e.Node.Checked;
       treeview1.EndUpdate();
      

      这对我有用。您必须在 AfterCheck EventHandler 中添加此代码。

      【讨论】:

        【解决方案3】:

        这是一个可以在 Visual Studio 的设计器中使用的简单控件:

        public class BetterTreeView : TreeView
        {
            /// <summary>
            /// Whether to apply Checked property changes to child nodes.
            /// </summary
            public bool TickChildNodes { get; set; }
        
            protected override void OnAfterCheck(TreeViewEventArgs e)
            {
                base.OnAfterCheck(e);
        
                if (TickChildNodes)
                {
                    foreach (TreeNode node in e.Node.Nodes)
                    {
                        node.Checked = e.Node.Checked; // Triggers OnAfterCheck (recursive)
                    }
                }
            }
        }
        

        【讨论】:

          【解决方案4】:

          没有与TreeView相关的HasChildNodes方法,你在这里混了XML的东西。

          public void CheckNodes(TreeNode startNode){
             startNode.Checked = true;
             foreach(TreeNode node in startNode.Nodes)
                CheckNodes(node);       
          }        
          //then you can call the method above with the TreeNode you check
          CheckNodes(yourNode);
          

          【讨论】:

          • 再次感谢这段代码,但对 c# 来说是相当新的我不确定这个代码块会去哪里?我不明白这个代码块是除了上面的代码块还是我的第一个问题的另一个解决方案?谢谢。
          • @user1292275 您只需在类中的某处定义CheckNodes 方法,然后每当您在AfterCheck 事件处理程序中检查一个节点时,调用CheckNodes 并传入检查的节点,那么所有的子节点也会被检查。
          • 我想通了。此代码块是我的问题的另一个解决方案。谢谢,效果很好!
          【解决方案5】:

          检查是否有子节点就足够了

          node.FirstNode != null
          

          至于您的第二个问题,您的代码似乎检查了孔树,而不仅仅是从给定的节点,然后我再次需要查看整个方法签名以及您将按下的节点保留在哪里。如果您在 myMember 之类的成员中拥有它,那么将该方法中的 treeView 更改为 myMember

              treeView.BeginUpdate();
              //Loop through all the nodes of tree
              foreach (TreeNode node in myMember.Nodes)
              {
                  //If node has child nodes
                  if (node.FirstNode != null)
                  {
                      if (node.Checked == true)
                      {
                          //Check all the child nodes.
                          foreach (TreeNode childNode in node.Nodes)
                          {
                              childNode.Checked = true;
                          }
                      }
                  }
              }
              treeView.EndUpdate();
          

          【讨论】:

            【解决方案6】:

            更正foreach循环:

            foreach (TreeNode node in treeView1.Nodes)
                    {
                        //If node has child nodes
                        if (node.Checked == true)   //it is better to first check if it is "checked" then proceed to count child nodes
                        {
                            if (node.GetNodeCount(false) > 0)   //check if node has any child nodes
                            {
                                //Check all the child nodes.
                                foreach (TreeNode childNode in node.Nodes)
                                {
                                    childNode.Checked = true;
                                }
                            }
                        }
                    }
            

            【讨论】:

            • 感谢您的帮助。此代码遍历整个树。如果我单击一个节点到树的一半并进入树,我将如何启动它? (并希望检查该节点的所有子节点)。
            【解决方案7】:

            检查父节点是检查..

            然后遍历所有子节点..

            if(e.Node.Checked==true)
                        {
                            foreach (TreeNode tn in e.Node.ChildNodes)
                            {
                                tn.Checked = true;
                            }
                        }
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2020-01-29
              相关资源
              最近更新 更多