C# 树形菜单的相关实现


在一些涉及到组织架构的场景, 比如ERP, OA系统中我们经常会需要用到树的结构。自己开发的时候也遇到了此使用场景,总结一下以后就可以直接拿来用了。

 表设计如下:

 代码如下:        

        public class Node
        {
            public int NodeId { get; set; }      //节点Id
            public int ParentId { get; set; }   //节点父级Id 如果为0则为根节点
            public string NodeName { get; set; }   //节点名
            public DateTime WriteTime { get; set; }  // 备注
        }

        public class TreeNode
        {
            public int NodeId { get; set; }      //节点Id
            public int ParentId { get; set; }   //节点父级Id 如果为0则为根节点
            public string NodeName { get; set; }   //节点名
            public DateTime WriteTime { get; set; }  //写入时间
            public List Children { get; set; }//子节点树
        }        
        
        /// 
        /// 获取当前系统的结构树,可能多个树
        /// 
        /// 
        public List GetSysNodeTree()
        {
            using (MySqlHelper mySqlHelper = new MySqlHelper("MySqlTestDB"))
            {
                List treeNodeList = new List();
                //这一步数据库查询所有的记录 (避免递归中多次查询数据库)
                List allNode = mySqlHelper.GetList_ExecuteSql("select * from tb_node");

                //遍历所有的根节点
                var rootList = allNode.Where(s => s.ParentId == 0).ToList();
                foreach (var ent in rootList)
                {
                    TreeNode treeNode = new TreeNode();
                    treeNode.NodeId = ent.NodeId;
                    treeNode.NodeName = ent.NodeName;
                    treeNode.ParentId = ent.ParentId;
                    treeNode.Children = GetChildrenTree(ent.NodeId, allNode);
                    treeNodeList.Add(treeNode);
                }

                return treeNodeList;
            }
        }

        /// 
        /// 获取当前节点的节点树
        /// 
        /// 
        /// 
        /// 
        public List GetChildrenTree(int curNodeId, List allNode)
        {
            if (allNode == null || allNode.Count <= 0)
                return new List();

            List TreeList = new List();
            List children = allNode.Where(s => s.ParentId == curNodeId).ToList();
            foreach (var ent in children)
            {
                TreeNode treeNode = new TreeNode();
                treeNode.NodeId = ent.NodeId;
                treeNode.NodeName = ent.NodeName;
                treeNode.ParentId = ent.ParentId;
                treeNode.Children = GetChildrenTree(ent.NodeId, allNode);
                TreeList.Add(treeNode);
            }

            return TreeList;
        }

        /// 
        /// 通过curNodeId 获取自己以及递归下的所有子Node (用于删除功能等)
        /// 
        /// 
        /// 
        /// 
        public List GetRecurNodes(int curNodeId, List allNode)
        {
            if (curNodeId <= 0 || allNode==null)
            {
                return null;
            }
            List list = new List();
            if (allNode.FirstOrDefault((m=>m.NodeId==curNodeId))!=null)
                list.Add(allNode.FirstOrDefault((m => m.NodeId == curNodeId)));
            List firstLevelNodes = allNode.Where(m => m.ParentId == curNodeId).ToList();
            foreach (var node in firstLevelNodes)
            {
                list.AddRange(GetRecurNodes(node.NodeId, allNode));
            }

            return list;
        }             

然后前端拿到数据,同样递归展示就OK了。

转载注明出处-祥子