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 else60  {61 curNode.Parent.Checked = false;62  CheckParentNode(curNode.Parent);63  }64  }65  }66 67 #endregion68 }

好了,那么在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 }

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

    

相关文章