场景描述:某个公司有多个部门并且部门存在子部门,通过一个下拉框选取多个部门,但是如果某个部门的子部门被全部选择,则只取该部门,而忽略子部门。(叶子节点全被选中时,只取父节点)
知识点:ComboTree、一般处理程序、递归、Json
效果如图

数据库表设计:unit_main

节点类设计:
public class Unit { public decimal id { get; set; } public string text { get; set; } public string state { get; set; } public List<Unit> children { get; set; } public Unit () { this.children = new List<Unit>(); this.state = "open"; } }
处理类设计:
public class UnitComponent { ExeceteOralceSqlHelper SqlHelper= new ExeceteOralceSqlHelper();//数据库处理类 public UnitParent GetUnit() {Unit rootUnit = new Unit();rootUnit.id = 1000;rootUnit.text = "BO API";rootUnit.children = GetUnitList(0);UnitRecursive(rootUnit.children);return rootUnit; } /// <summary> /// 递归查询部门 /// </summary> /// <param name="units"></param> private void UnitRecursive(List<Unit> units) {foreach (var item in units){item.children = GetUnitList(item.id);if (item.children != null && item.children.Count > 0){ item.state = "closed"; UnitRecursive(item.children);}} } /// <summary> /// 通过parentID获取所有子部门 /// </summary> /// <param name="parentID">父id</param> /// <returns>返回Unit集合</returns> private List<Unit> GetUnitList(decimal parentID) {List<Unit> unitLst = new List<Unit>();string sql = string.Format("select hh.unit_id,hh.unit_name from unit_main hh where hh.parent_id={0}", parentID);DataTable dt = SqlHelper.ExecuteDataTable(sql);//返回DataTable方法if (dt != null && dt.Rows.Count > 0){for (int i = 0; i < dt.Rows.Count; i++){ Unit dtup = new Unit() { id = Convert.ToInt32(dt.Rows[i]["unit_id"]), text = dt.Rows[i]["unit_name"].ToString() }; unitLst.Add(dtup);}}return unitLst; }}下面,新建web应用程序-添加-一般处理程序,其中JavaScriptSerializer你可以换为NewtonSoft来处理
public void ProcessRequest(HttpContext context){ JavaScriptSerializer js = new JavaScriptSerializer(); context.Response.ContentType = "application/json"; UnitComponent uc = new SynUser.UnitComponent(); var unit = uc.GetUnit(); context.Response.Write("[" + js.Serialize(unit) + "]");}现在我们测试一下这个一般处理程序,如果像图片一样返回了结果说明正确:

好了,部门结构的数据准备好了,下开始写前台代码:
新建一个aspx页面,拖一个控件
<asp:TextBox ID="tbUnit" runat="server" Width="280px"></asp:TextBox>
引入相应的js,在script加入代码
$("#tbUnit").combotree({ url: , "/unit.ashx" cascadeCheck: true, placeholder: "请选择部门", method: "get", required: true, multiple: true, onChange: function (newValue, oldValue) { computeunit(); }, onLoadSuccess: function (node, data) { }}); 
不知你有没有发现我选中的是应用管理服务中心、xiaobo、tech三个节点,但是xiaobo、tech是应用服务中心的叶子节点。需求要求,我们只需获取应用管理服务中心节点,不需要在获取xiaobo、tech。
所有要通过js遍历tree来获取我们想要的节点,computerunit方法是我们想要的。
思路为:递归获取被选的子节点,然后与所选的节点作差集,最后的得到的就是被选的节点(不包括全选的子节点)
function computeunit() {var arr = new Array();var selectstr = $("#tbUnit").combotree("getValues").toString();var select = selectstr.split(",");var t = $("#tbUnit").combotree("tree"); // get the tree objectvar n = t.tree("getChecked"); // get selected nodeunitrecursive(t, n, arr);alert(subtraction(select, arr).join(",")); } /*计算数组差集 **返回结果数组 */ function subtraction(arr1, arr2) {var res = [];for (var i = 0; i < arr1.length; i++) {var flag = true;for (var j = 0; j < arr2.length; j++) { if (arr2[j] == arr1[i]) { flag = false; }}if (flag) { res.push(arr1[i]);}}return res; } /*获取被选父节点的子项目 **返回结果arr里 */ function unitrecursive(t, nodes, arr) {for (var i = 0; i < nodes.length; i++) {if (!t.tree("isLeaf", nodes[i].target)) { var nn = t.tree("getChildren", nodes[i].target); for (var j = 0; j < nn.length; j++) { arr.push(nn[j].id); } unitrecursive(t, nn, arr);}} }以上就是ASP.NET实现下拉树(Easy UI ComboTree)的全部思路,希望对大家的学习有所帮助。