日常开发中,经常需要实现多选的树结构,并且可能存在多级节点的情况。
以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 }
好了,思路就是这样,可以拿去参考。