Web 开发中经常用到 TreeView 控件,一个很常见的操作就是遍历所有的节点。但是该控件本身并未提供此功能,每次都要手工写递归访问的函数,非常烦琐。所以我写了一个简单的帮助类来解决这个问题,这样就不需要每次用递归来访问了:
- using System;
- using System.Data;
- using System.Configuration;
- using System.Web;
- using System.Web.Security;
- using System.Web.UI;
- using System.Web.UI.WebControls;
- using System.Web.UI.WebControls.WebParts;
- using System.Web.UI.HtmlControls;
- using System.Collections.Generic;
- namespace CmsNet2.Components {
- /// <summary>
- /// TreeViewVisitor by Neil Chen, 2006-09-28
- /// </summary>
- public class TreeViewVisitor {
- public TreeViewVisitor(TreeView treeView) {
- this.treeView = treeView;
- }
- private TreeView treeView;
- public TreeView TreeView {
- get { return treeView; }
- set { treeView = value; }
- }
- private void Walk(TreeNode node) {
- if (node == null) {
- nodes.Add(treeView.Nodes[0]);
- foreach (TreeNode childNode in treeView.Nodes[0].ChildNodes) {
- Walk(childNode);
- }
- } else {
- nodes.Add(node);
- foreach (TreeNode childNode in node.ChildNodes) {
- Walk(childNode);
- }
- }
- }
- private List<TreeNode> nodes;
- public IEnumerable<TreeNode> GetAllTreeNodes() {
- nodes = new List<TreeNode>();
- Walk(null);
- foreach (TreeNode node in nodes) {
- yield return node;
- }
- }
- }
- }
一个简单的使用范例:遍历所有节点,并将符合条件的节点选中。
- public void SetCheckedCategories(List<Category> categories) {
- // 创建访问器对象
- TreeViewVisitor visitor = new TreeViewVisitor(tvCategories);
- // 得到“铺平”了的所有节点集合
- IEnumerable<TreeNode> nodes = visitor.GetAllTreeNodes();
- // 进行你需要的访问操作
- foreach (TreeNode node in nodes) {
- foreach (Category category in categories) {
- if (category.CategoryId == int.Parse(node.Value)) {
- node.Checked = true;
- }
- }
- }
- }
当然,目前这个类的应用范围很局限,仅仅限于 TreeView 控件。但如果我们进一步思考,则可以很容易的推广到对普通的树状结构,或者多级菜单的访问逻辑中。从而实现与具体控件无关的访问逻辑。