原文:https://www.cnblogs.com/fzz2727551894/p/5501223.html
简单测试:
前端:
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title></title> </head> <body> <div id="plugins1"></div> <link href="../jstree/themes/default/style.min.css" rel="stylesheet" /> <script src="https://cdn.bootcss.com/jquery/1.12.4/jquery.js"></script> <script src="../jstree/jstree.min.js"></script> <link href="../layui-v2.5.5/layui/css/layui.css" rel="stylesheet" /> <script type="text/javascript"> var data = [ { "text": "Root node 1", "id": "1", "state": { "opened": true }, "children": [ { "text": "Child node 11", "id": "11", "state": { "opened": true, //"selected": false//默认不选中 }, type: 'nouser'//设置图标类型 }, { "text": "Child node 22", "id": "22", "state": { "opened": true, //"selected": true,//默认选中 //"checked": true }, "children": [ { "text": "Child node 221", "id": "221", "state": { "opened": true } }, { "text": "Child node 222", "id": "222", "state": { "opened": true }, } ] }, { "text": "Child node 33", "id": "33", "state": { "opened": true, //"selected": true,//默认选中 //"checked": true } } ] } ]; //Checkbox plugin $(function () { $("#plugins1").jstree({ "checkbox": { //"keep_selected_style": true//显示选中的样式 //"keep_selected_style": false,// 保持选中样式 true为保持,false为不保存,样式不影响功能 'three_state': true,//父子节点关联,true为关联,false为不关联 'tie_selection': false, // 'whole_node': false,//复选框与节点关联 true 为关联 false为不关联 }, "types": { 'nouser': { "icon": 'layui-icon layui-icon-ok' } }, "plugins": ["checkbox", "types"],//加载插件 checkbox 'core': { 'expand_selected_onload': true,//加载完成后默认展开所有选中节点true为选中 false为不展开 'themes': { dots: true //取消连接线 }, 'data': { 'url': function (node) { return './Handler4.ashx'; }, 'data': function (node) { return { 'id': node.id }; } } } }); //checkbox 选中事件 $('#plugins1').on("check_node.jstree", function (node, data, event) { //console.log(node); //console.log(data); console.log(data.node.original.code); }); }); </script> </body> </html>
后台:
using System; using System.Collections.Generic; using System.Data; using System.Data.SqlClient; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ConsoleApp1 { public class Class6 { //https://www.cnblogs.com/fzz2727551894/p/5501223.html public void test1() { var dt = ExecuteDataTable($"select * from Table_1 ", null); List<TreeNode> tree = TreeServices.ToTree(dt); Console.WriteLine(tree.Count); } // 返回DataTable public static DataTable ExecuteDataTable(string sql, params SqlParameter[] param) { string conStr = "data source=.\sqlexpress;initial catalog=TEST1;user id=sa;password=sa;"; //string conStr = "data source=192.168.2.51; initial catalog=BIMManagerDb;user id=sa;password=Sql123456; "; DataTable dt = new DataTable(); using (SqlConnection con = new SqlConnection(conStr)) { using (SqlDataAdapter adapter = new SqlDataAdapter(sql, con)) { //添加参数 if (param != null) { adapter.SelectCommand.Parameters.AddRange(param); } //1.打开链接,如果连接没有打开,则它给你打开;如果打开,就算了 //2.去执行sql语句,读取数据库 //3.sqlDataReader,把读取到的数据填充到内存表中 adapter.Fill(dt); } } return dt; } } public static class k1 { public static bool IsEmpty(this string str) { return false; } public static bool IsEmpty(this DataTable dt) { if (dt == null) { return true; } if (dt.Rows.Count <= 0) { return true; } return false; } public static int ToInt32(this object obj) { return int.Parse(obj.ToString()); } public static bool IsEmpty<T>(this List<T> list) where T : class, new() { return false; } } public class TreeServices { /// <summary> /// 以非递归的方式生成树 /// </summary> /// <param name="table"></param> /// <returns></returns> public static List<TreeNode> ToTree(DataTable table) { var list = new List<TreeNode>(); if (table.IsEmpty()) return list; var dic = TreeNode.FillModel(table); foreach (var pair in dic) { var pid = pair.Value.ParentId; if (pid == 0) { list.Add(pair.Value); continue; } if (dic.ContainsKey(pid)) { dic[pid].Children.Add(pair.Value); } } return list; } } public class TreeNode { public TreeNode() { Children = new List<TreeNode>(); } /// <summary> /// 自增Id /// </summary> public int NodeId { get; set; } /// <summary> /// 关联Id,形式1-2-3-4(该节点上一节点为4,再上一级为3,...) /// </summary> public string RelationId { get; set; } /// <summary> /// 上一个节点的Id /// </summary> public int ParentId { get { if (RelationId.IsEmpty()) return 0; var s = RelationId.Split('-'); return s[s.Length - 1].ToInt32(); } } /// <summary> /// 是否有下一节点 /// </summary> public bool HasChild { get { return Children.IsEmpty(); } } /// <summary> /// 子节点集合 /// </summary> public List<TreeNode> Children { get; set; } /// <summary> /// DataTable To Dictionary /// </summary> /// <param name="table"></param> /// <returns></returns> public static Dictionary<int, TreeNode> FillModel(DataTable table) { var list = new Dictionary<int, TreeNode>(); if (table == null || table.Rows.Count == 0) return list; foreach (DataRow row in table.Rows) { var model = new TreeNode { NodeId = row["Id"].ToInt32(), RelationId = row["RelationId"].ToString() }; list.Add(model.NodeId, model); } return list; } } }
SQL:
USE [TEST1] GO /****** Object: Table [dbo].[Table_1] Script Date: 03/11/2020 11:36:54 ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO CREATE TABLE [dbo].[Table_1]( [Id] [int] NOT NULL, [RelationId] [nvarchar](max) NULL, [ParentId] [int] NULL, CONSTRAINT [PK_Table_1] PRIMARY KEY CLUSTERED ( [Id] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY] GO INSERT [dbo].[Table_1] ([Id], [RelationId], [ParentId]) VALUES (1, N'0', 0) INSERT [dbo].[Table_1] ([Id], [RelationId], [ParentId]) VALUES (2, N'1', 1) INSERT [dbo].[Table_1] ([Id], [RelationId], [ParentId]) VALUES (3, N'1', 1) INSERT [dbo].[Table_1] ([Id], [RelationId], [ParentId]) VALUES (4, N'1-3', 3)