C#:TreeView控件实现带子节点的多选树结构

日常开发中,经常需要实现多选的树结构,并且可能存在多级节点的情况。

以WinFrom为例,下面是本人的总结。 首先创建一个TreeView 名称为 tvTest,下面开始添加主子节点。

 1           TreeView tvTest=new TreeView();
 2 
 3            tvTest.BeginUpdate();
 4 
 5             for (int i = 0; i < 5; i++)
 6             {
 7                 TreeNode node = new TreeNode();
 8                 node.Tag = i+1;
 9                 node.Text = "父节点"+(i+1).Tostring();
10                 node.Name = "application";
11 
12                 //node.ImageIndex = 1;
13                 //node.SelectedImageIndex = 1;
14 
15                 tvTest.Nodes.Add(node);
16 
17                 for (int j = 0; j < 4; j++)
18                 {
19                     TreeNode childNode = new TreeNode();
20                     childNode.Tag = "子节点" + (j + 1).ToString();
21                     childNode.Text = "子节点" + (j + 1).ToString();
22                     node.Nodes.Add(childNode);
23                 }
24             }
25             tvTest.EndUpdate();
26         

 新建一个类TreeViewCheck,用于TreeView父子级节点的选择事件,实现父级节点选中子节点跟着选择的效果。

 1  public static class TreeViewCheck
 2     {
 3         /// <summary>
 4         /// 系列节点 Checked 属性控制
 5         /// </summary>
 6         /// <param name="e"></param>
 7         public static void CheckControl(TreeViewEventArgs e)
 8         {
 9             if (e.Action != TreeViewAction.Unknown)
10             {
11                 if (e.Node != null && !Convert.IsDBNull(e.Node))
12                 {
13                     CheckParentNode(e.Node);
14                     if (e.Node.Nodes.Count > 0)
15                     {
16                         CheckAllChildNodes(e.Node, e.Node.Checked);
17                     }
18                 }
19             }
20         }
21 
22         #region 私有方法
23 
24         //改变所有子节点的状态
25         private static void CheckAllChildNodes(TreeNode pn, bool IsChecked)
26         {
27             foreach (TreeNode tn in pn.Nodes)
28             {
29                 tn.Checked = IsChecked;
30 
31                 if (tn.Nodes.Count > 0)
32                 {
33                     CheckAllChildNodes(tn, IsChecked);
34                 }
35             }
36         }
37 
38         //改变父节点的选中状态,此处为所有子节点不选中时才取消父节点选中,可以根据需要修改
39         private static void CheckParentNode(TreeNode curNode)
40         {
41             bool bChecked = false;
42 
43             if (curNode.Parent != null)
44             {
45                 foreach (TreeNode node in curNode.Parent.Nodes)
46                 {
47                     if (node.Checked)
48                     {
49                         bChecked = true;
50                         break;
51                     }
52                 }
53 
54                 if (bChecked)
55                 {
56                     curNode.Parent.Checked = true;
57                     CheckParentNode(curNode.Parent);
58                 }
59                 else
60                 {
61                     curNode.Parent.Checked = false;
62                     CheckParentNode(curNode.Parent);
63                 }
64             }
65         }
66 
67         #endregion
68     }

好了,那么在TreeView的选择事件中调用。

1 private void tvTest_AfterCheck(object sender, TreeViewEventArgs e)
2 {
3    TreeViewCheck.CheckControl(e);
4 }

实现的效果如下:

最后的关键,如何获取我选择到的节点值呢?

这里使用whlie循环取每个父级节点的子节点。

代码如下:

 1 List<string> lstSelect=new List<string>();  //保存值的list
 2   
 3  //选择第一个节点
 4             TreeNode selectNodes = tvTest.Nodes[0];
 5             while (selectNodes != null)
 6             {
 7                 TreeNode childNode = null;          //根节点的被选中的子节点
 8 
 9                 childNode = selectNodes.FirstNode;
10                 while (childNode != null)           //找该节点的所有被选择的子节点
11                 {
12                     if (childNode.Checked)
13                     {
14                         //处理数据。保存节点的值
15 
16                         lstSelect.Add(childNode.Tag.ToString());
17                     }
18                     childNode = childNode.NextNode;
19                 }
20                 selectNodes = selectNodes.NextNode;          //下一个被选中的节点
21             }

好了,思路就是这样,可以拿去参考。

    

posted @ 2020-06-17 17:56  Healer2047  阅读(2423)  评论(0编辑  收藏  举报