• 不再为无限级树结构烦恼,且看此篇s


    很久都没有写点什么出来分享了,最近在做多级树的时候,发现来来回回写过很多遍,于是封装成用户控件,以方便日后重复使用.

    首先上效果:

    我们看到以上2种效果,都是支持任意级的,这里源码中使用的是递归,以便高效的完成HTML的渲染.

    下面上代码,代码中解释的都很详细了,我就不再细说.下面将有示例调用演示:

      1 public partial class  UC_MultiLevelTree : System.Web.UI.UserControl
      2 {
      3     #region 数据相关属性
      4 
      5     /// <summary>
      6     /// 要绑定的数据源
      7     /// </summary>
      8     public DataTable DataSource { get; set; }
      9 
     10     /// <summary>
     11     /// 多级树显示文本所在列列名
     12     /// </summary>
     13     public string TextFeild { get; set; }
     14 
     15     /// <summary>
     16     /// 多级树单条数据识别列列名(即选择项的值)
     17     /// </summary>
     18     public string ValueFeild { get; set; }
     19 
     20     /// <summary>
     21     /// 多级树层级区别列列名(仅限单个列区分层级)
     22     /// </summary>
     23     public string LevelFeild { get; set; }
     24 
     25     /// <summary>
     26     /// 多级树顶级的父项值
     27     /// </summary>
     28     public string TopLevelFeildValue { get; set; }
     29 
     30     #endregion
     31 
     32     #region 显示相关属性
     33 
     34     /// <summary>
     35     /// 是否显示多选框,默认为显示
     36     /// </summary>
     37     public bool ShowCheckBox { get; set; }
     38 
     39     /// <summary>
     40     /// 是否显示自定义根节点
     41     /// </summary>
     42     public bool ShowCustomerRoot { get; set; }
     43 
     44     /// <summary>
     45     /// 自定义根节点文本
     46     /// </summary>
     47     public string CustomerRootText { get; set; }
     48 
     49     /// <summary>
     50     /// 多级树宽度,可为像素或者百分比
     51     /// </summary>
     52     public string Width { get; set; }
     53 
     54     /// <summary>
     55     /// 多级树高度,可为像素或者百分比
     56     /// </summary>
     57     public string Height { get; set; }
     58 
     59     /// <summary>
     60     /// 展开符号(可为HTML代码)
     61     /// </summary>
     62     public string ExtendSign { get; set; }
     63 
     64     /// <summary>
     65     /// 收缩符号(可为HTML代码)
    
     66     /// </summary>
     67     public string ShrinkSign { get; set; }
     68 
     69     /// <summary>
     70     /// 每级与上级空格个数
     71     /// </summary>
     72     public int LevelSeparatorCount { get; set; }
     73 
     74     /// <summary>
     75     /// 默认展开级别
     76     /// </summary>
     77     public int ExtendLevelNum { get; set; }
     78 
     79     #endregion
     80 
     81     #region 私有变量
     82 
     83     /// <summary>
     84     /// 扩展标记的HTML
     85     /// </summary>
     86     private string StrExtendSign;
     87 
     88     /// <summary>
     89     /// 收缩标记的HTML
     90     /// </summary>
     91     private string StrShrinkSign;
     92 
     93     /// <summary>
     94     /// 多选框的HTML
     95     /// </summary>
     96     private string StrCheckbox;
     97 
     98     /// <summary>
     99     /// 子层级开始符号的HTML
    100     /// </summary>
    101     private string LevelSeparator = "&nbsp;";
    102 
    103     #endregion
    104 
    105 
    106     protected override void OnInit(EventArgs e)
    107     {
    108         base.OnInit(e);
    109         this.ShowCheckBox = true;
    110         this.Width = "100%";
    111         this.Height = "100%";
    112         this.ExtendSign = "[+]";
    113         this.ShrinkSign = "[-]";
    114         this.TopLevelFeildValue = CRMCommon.strNullGuid;
    115         this.LevelSeparatorCount = 4;
    116         this.ExtendLevelNum = 2;
    117     }
    118 
    119 
    120     protected void Page_Load(object sender, EventArgs e)
    121     {
    122 
    123     }
    124 
    125     public void DataBind()
    126     {
    127         this.StrCheckbox = this.ShowCheckBox ? "<input type='checkbox' class='MLT_Checkbox'/>" : "";
    128         this.StrExtendSign = "<span class='MLT_ExtendSign' {0}>" + this.ExtendSign + "</span>";
    129         this.StrShrinkSign = "<span class='MLT_ShrinkSign' {0}>" + this.ShrinkSign + "</span>";
    130         this.ltMultiLevelTreeHtml.Text = RenderTree(this.TopLevelFeildValue, 1);
    131     }
    132 
    133 
    134     private string RenderTree(string parentValue, int level)
    135     {
    136         StringBuilder sb = new StringBuilder();
    137 
    138         string extendSignHtml = "";
    139         string shrinkSignHtml = "";
    140 
    141         //收缩,展开按钮的显示控制
    142         if (level < this.ExtendLevelNum)
    143         {
    144             extendSignHtml = string.Format(this.StrExtendSign, "style='display:none;'");
    145             shrinkSignHtml = string.Format(this.StrShrinkSign, "");
    146         }
    147         else
    148         {
    149             extendSignHtml = string.Format(this.StrExtendSign, "");
    150             shrinkSignHtml = string.Format(this.StrShrinkSign, "style='display:none;'");
    151         }
    152 
    153         //自定义根节点
    154         if (level == 1)
    155         {
    156             sb.AppendFormat("<div class='MLT_Panel' style='{0};height:{1}'>", this.Width, this.Height);
    157             if (this.ShowCustomerRoot)
    158             {
    159                 sb.AppendFormat("<div class='MLT_Item' level='{0}' rel=''>{1}<span class='MLT_Item_Text'>{2}</span></div>", level, extendSignHtml + shrinkSignHtml + this.StrCheckbox, this.CustomerRootText);
    160 
    161                 level += 1;
    162             }
    163             sb.Append(RenderTree(parentValue, level));
    164             sb.Append("</div>");
    165         }
    166 
    167         else if (level != 1)
    168         {
    169             //数据项绑定
    170             if (this.DataSource != null && this.DataSource.Rows.Count > 0)
    171             {
    172                 string levelSeparator = "";
    173 
    174                 if (level > 1)
    175                 {
    176                     levelSeparator += "<span  class='MLT_LevelSeparator'>";
    177                     for (int i = 1; i <= (level - 1) * this.LevelSeparatorCount; i++)
    178                     {
    179                         levelSeparator += this.LevelSeparator;
    180                     }
    181                     levelSeparator += "</span>";
    182                 }
    183 
    184                 DataRow[] drList = this.DataSource.Select(string.Format("{0}='{1}'", this.LevelFeild, parentValue));
    185 
    186                 if (drList != null && drList.Length > 0)
    187                 {
    188                     level += 1;
    189                     foreach (DataRow dr in drList)
    190                     {
    191                         string childHtml = RenderTree(dr[ValueFeild].ToString(), level);
    192 
    193                         string signs = string.IsNullOrWhiteSpace(childHtml) ? "<span  class='MLT_ExtendSignPlaceholder'></span>" : extendSignHtml + shrinkSignHtml;
    194 
    195                         sb.AppendFormat("<div class='MLT_Item' level='{0}' rel='{1}' parent='{2}' {3}>{4}<span class='MLT_Item_Text'>{5}</span></div>", level - 1, dr[ValueFeild], dr[LevelFeild], level - 1 > this.ExtendLevelNum ? "style='display:none;'" : "", levelSeparator + signs + this.StrCheckbox, dr[TextFeild]);
    196 
    197                         if (!string.IsNullOrWhiteSpace(childHtml))
    198                         {
    199                             sb.Append(childHtml);
    200                         }
    201                     }
    202                 }
    203             }
    204         }
    205         return sb.ToString();
    206 
    207     }
    208 }
    View Code
      1 <%@ Control Language="C#" AutoEventWireup="true" CodeFile="UC_MultiLevelTree.ascx.cs" Inherits="UC_MultiLevelTree" %>
      2 <asp:Literal runat="server" ID="ltMultiLevelTreeHtml"></asp:Literal>
      3 <script>
      4     $(function () {
      5         $(".MLT_Item").click(function (e) {
      6             e.stopPropagation();
      7             $(".MLT_Item").removeClass("MLT_Item_hover");
      8             $(this).addClass("MLT_Item_hover");
      9             extendItem(this);
     10         });
     11 
     12         $(".MLT_ExtendSign").click(function (e) {
     13             e.stopPropagation();
     14             var event = e.currentTarget;
     15             var item = $(event).parent();
     16             extendItem(item);
     17         })
     18 
     19         $(".MLT_ShrinkSign").click(function (e) {
     20             e.stopPropagation();
     21             var event = e.currentTarget;
     22             var item = $(event).parent();
     23             shrinkItem(item);
     24         })
     25 
     26         $(".MLT_Checkbox").click(function (e) {
     27             e.stopPropagation();
     28             var event = e.currentTarget;
     29             var item = $(event).parent();
     30             var checked = $(event).attr("checked");
     31             checkItems(item, checked);
     32         });
     33     });
     34 
     35     //展开项
     36     function extendItem(obj) {
     37         var rel = $(obj).attr("rel");
     38         if (rel != undefined && rel.length > 0) {
     39             $(obj).siblings("div[parent=" + rel + "]").each(function () {
     40                 $(this).show();
     41             });
     42         }
     43         else {
     44             $(obj).siblings("div[level=2]").show();
     45         }
     46         $(obj).find(".MLT_ExtendSign").hide();
     47         $(obj).find(".MLT_ShrinkSign").show();
     48     }
     49 
     50     //收缩项
     51     function shrinkItem(obj) {
     52         var rel = $(obj).attr("rel");
     53         if (rel != undefined && rel.length > 0) {
     54             $(obj).siblings("div[parent=" + rel + "]").each(function () {
     55                 $(this).hide();
     56                 $(this).find(".MLT_ExtendSign").show();
     57                 $(this).find(".MLT_ShrinkSign").hide();
     58                 shrinkItem(this);
     59             });
     60         }
     61         else {
     62             $(obj).siblings("div[level!=1]").hide();
     63             $(obj).siblings("div[level!=1]").find(".MLT_ExtendSign").show();
     64             $(obj).siblings("div[level!=1]").find(".MLT_ShrinkSign").hide();
     65         }
     66         $(obj).find(".MLT_ExtendSign").show();
     67         $(obj).find(".MLT_ShrinkSign").hide();
     68     }
     69 
     70     //选择项
     71     function checkItems(obj, checked) {
     72         var rel = $(obj).attr("rel");
     73         if (rel != undefined && rel.length > 0) {
     74             if (checked) {
     75                 $(obj).siblings("div[parent=" + rel + "]").each(function () {
     76                     $(this).find("input[type=checkbox]").attr("checked", "checked");
     77                     checkItems(this, checked);
     78                 });
     79             }
     80             else {
     81                 $(obj).siblings("div[parent=" + rel + "]").each(function () {
     82                     $(this).find("input[type=checkbox]").removeAttr("checked");
     83                     checkItems(this, checked);
     84                 });
     85             }
     86         }
     87         else {
     88             if (checked) {
     89                 $(obj).parent().find("input[type=checkbox]").attr("checked", "checked");
     90             }
     91             else {
     92                 $(obj).parent().find("input[type=checkbox]").removeAttr("checked");
     93             }
     94         }
     95     }
     96 </script>
     97 <style type="text/css">
     98     .MLT_Panel
     99     {
    100         white-space: nowrap;
    101         overflow: auto;
    102     }
    103 
    104     .MLT_Item
    105     {
    106         font-size: 12px;
    107         line-height: 20px;
    108         cursor: pointer;
    109     }
    110 
    111     .MLT_Item_hover
    112     {
    113         background-color: rgb(167, 205, 240);
    114     }
    115 
    116     .MLT_Item span
    117     {
    118         line-height: 20px;
    119         display: inline-block;
    120     }
    121 
    122     .MLT_Checkbox
    123     {
    124         position: relative;
    125          12px;
    126         height: 12px;
    127         margin: 0 2px;
    128         bottom: 2px;
    129     }
    130 
    131     .MLT_ExtendSign, .MLT_ShrinkSign, .MLT_ExtendSignPlaceholder
    132     {
    133         font-family: "宋体";
    134          18px;
    135         text-align: center;
    136     }
    137 </style>
    View Code

    示例:

    使用原数据:

    生成HTML中,每一级每一条都包含在使用相同class的DIV当中,不同之外在于自定义的level,parent,rel等属性,请参见代码.

    下列为调用代码方法,各参数可自行设定,说见用户控件CS代码:

    由于时间问题,可能很多地方不便细说.如有更多疑问,请加QQ群:ASP.NET高级群,群号: 261882616

  • 相关阅读:
    一次心惊肉跳的服务器误删文件的恢复过程
    ThreadPoolExecutor使用详解
    Springboot学习笔记(一)-线程池的简化及使用
    springboot之异步调用@Async
    CentOS 7添加开机启动服务/脚本
    三分钟在任何电脑上使用 chrome os
    Spring Cloud Alibaba基础教程:Sentinel Dashboard中修改规则同步到Nacos
    Nacos部署中的一些常见问题汇总
    Spring Cloud Alibaba基础教程:Sentinel Dashboard中修改规则同步到Apollo
    Spring Cloud Alibaba 新版本发布:众多期待内容整合打包加入!
  • 原文地址:https://www.cnblogs.com/lilin123/p/3227229.html
Copyright © 2020-2023  润新知