zoukankan      html  css  js  c++  java
  • 无限级树结构

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

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

    首先上效果:

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

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

     View Code

    public partial class UC_MultiLevelTree : System.Web.UI.UserControl
    {
    #region 数据相关属性

    /// <summary>
    /// 要绑定的数据源
    /// </summary>
    public DataTable DataSource { get; set; }

    /// <summary>
    /// 多级树显示文本所在列列名
    /// </summary>
    public string TextFeild { get; set; }

    /// <summary>
    /// 多级树单条数据识别列列名(即选择项的值)
    /// </summary>
    public string ValueFeild { get; set; }

    /// <summary>
    /// 多级树层级区别列列名(仅限单个列区分层级)
    /// </summary>
    public string LevelFeild { get; set; }

    /// <summary>
    /// 多级树顶级的父项值
    /// </summary>
    public string TopLevelFeildValue { get; set; }

    #endregion

    #region 显示相关属性

    /// <summary>
    /// 是否显示多选框,默认为显示
    /// </summary>
    public bool ShowCheckBox { get; set; }

    /// <summary>
    /// 是否显示自定义根节点
    /// </summary>
    public bool ShowCustomerRoot { get; set; }

    /// <summary>
    /// 自定义根节点文本
    /// </summary>
    public string CustomerRootText { get; set; }

    /// <summary>
    /// 多级树宽度,可为像素或者百分比
    /// </summary>
    public string Width { get; set; }

    /// <summary>
    /// 多级树高度,可为像素或者百分比
    /// </summary>
    public string Height { get; set; }

    /// <summary>
    /// 展开符号(可为HTML代码)
    /// </summary>
    public string ExtendSign { get; set; }

    /// <summary>
    /// 收缩符号(可为HTML代码)
    /// </summary>
    public string ShrinkSign { get; set; }

    /// <summary>
    /// 每级与上级空格个数
    /// </summary>
    public int LevelSeparatorCount { get; set; }

    /// <summary>
    /// 默认展开级别
    /// </summary>
    public int ExtendLevelNum { get; set; }

    #endregion

    #region 私有变量

    /// <summary>
    /// 扩展标记的HTML
    /// </summary>
    private string StrExtendSign;

    /// <summary>
    /// 收缩标记的HTML
    /// </summary>
    private string StrShrinkSign;

    /// <summary>
    /// 多选框的HTML
    /// </summary>
    private string StrCheckbox;

    /// <summary>
    /// 子层级开始符号的HTML
    /// </summary>
    private string LevelSeparator = "&nbsp;";

    #endregion


    protected override void OnInit(EventArgs e)
    {
    base.OnInit(e);
    this.ShowCheckBox = true;
    this.Width = "100%";
    this.Height = "100%";
    this.ExtendSign = "[+]";
    this.ShrinkSign = "[-]";
    this.TopLevelFeildValue = CRMCommon.strNullGuid;
    this.LevelSeparatorCount = 4;
    this.ExtendLevelNum = 2;
    }


    protected void Page_Load(object sender, EventArgs e)
    {

    }

    public void DataBind()
    {
    this.StrCheckbox = this.ShowCheckBox ? "<input type='checkbox' class='MLT_Checkbox'/>" : "";
    this.StrExtendSign = "<span class='MLT_ExtendSign' {0}>" + this.ExtendSign + "</span>";
    this.StrShrinkSign = "<span class='MLT_ShrinkSign' {0}>" + this.ShrinkSign + "</span>";
    this.ltMultiLevelTreeHtml.Text = RenderTree(this.TopLevelFeildValue, 1);
    }


    private string RenderTree(string parentValue, int level)
    {
    StringBuilder sb = new StringBuilder();

    string extendSignHtml = "";
    string shrinkSignHtml = "";

    //收缩,展开按钮的显示控制
    if (level < this.ExtendLevelNum)
    {
    extendSignHtml = string.Format(this.StrExtendSign, "style='display:none;'");
    shrinkSignHtml = string.Format(this.StrShrinkSign, "");
    }
    else
    {
    extendSignHtml = string.Format(this.StrExtendSign, "");
    shrinkSignHtml = string.Format(this.StrShrinkSign, "style='display:none;'");
    }

    //自定义根节点
    if (level == 1)
    {
    sb.AppendFormat("<div class='MLT_Panel' style='{0};height:{1}'>", this.Width, this.Height);
    if (this.ShowCustomerRoot)
    {
    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);

    level += 1;
    }
    sb.Append(RenderTree(parentValue, level));
    sb.Append("</div>");
    }

    else if (level != 1)
    {
    //数据项绑定
    if (this.DataSource != null && this.DataSource.Rows.Count > 0)
    {
    string levelSeparator = "";

    if (level > 1)
    {
    levelSeparator += "<span class='MLT_LevelSeparator'>";
    for (int i = 1; i <= (level - 1) * this.LevelSeparatorCount; i++)
    {
    levelSeparator += this.LevelSeparator;
    }
    levelSeparator += "</span>";
    }

    DataRow[] drList = this.DataSource.Select(string.Format("{0}='{1}'", this.LevelFeild, parentValue));

    if (drList != null && drList.Length > 0)
    {
    level += 1;
    foreach (DataRow dr in drList)
    {
    string childHtml = RenderTree(dr[ValueFeild].ToString(), level);

    string signs = string.IsNullOrWhiteSpace(childHtml) ? "<span class='MLT_ExtendSignPlaceholder'></span>" : extendSignHtml + shrinkSignHtml;

    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]);

    if (!string.IsNullOrWhiteSpace(childHtml))
    {
    sb.Append(childHtml);
    }
    }
    }
    }
    }
    return sb.ToString();

    }
    }

     View Code

    <%@ Control Language="C#" AutoEventWireup="true" CodeFile="UC_MultiLevelTree.ascx.cs" Inherits="UC_MultiLevelTree" %>
    <asp:Literal runat="server" ID="ltMultiLevelTreeHtml"></asp:Literal>
    <script>
    $(function () {
    $(".MLT_Item").click(function (e) {
    e.stopPropagation();
    $(".MLT_Item").removeClass("MLT_Item_hover");
    $(this).addClass("MLT_Item_hover");
    extendItem(this);
    });

    $(".MLT_ExtendSign").click(function (e) {
    e.stopPropagation();
    var event = e.currentTarget;
    var item = $(event).parent();
    extendItem(item);
    })

    $(".MLT_ShrinkSign").click(function (e) {
    e.stopPropagation();
    var event = e.currentTarget;
    var item = $(event).parent();
    shrinkItem(item);
    })

    $(".MLT_Checkbox").click(function (e) {
    e.stopPropagation();
    var event = e.currentTarget;
    var item = $(event).parent();
    var checked = $(event).attr("checked");
    checkItems(item, checked);
    });
    });

    //展开项
    function extendItem(obj) {
    var rel = $(obj).attr("rel");
    if (rel != undefined && rel.length > 0) {
    $(obj).siblings("div[parent=" + rel + "]").each(function () {
    $(this).show();
    });
    }
    else {
    $(obj).siblings("div[level=2]").show();
    }
    $(obj).find(".MLT_ExtendSign").hide();
    $(obj).find(".MLT_ShrinkSign").show();
    }

    //收缩项
    function shrinkItem(obj) {
    var rel = $(obj).attr("rel");
    if (rel != undefined && rel.length > 0) {
    $(obj).siblings("div[parent=" + rel + "]").each(function () {
    $(this).hide();
    $(this).find(".MLT_ExtendSign").show();
    $(this).find(".MLT_ShrinkSign").hide();
    shrinkItem(this);
    });
    }
    else {
    $(obj).siblings("div[level!=1]").hide();
    $(obj).siblings("div[level!=1]").find(".MLT_ExtendSign").show();
    $(obj).siblings("div[level!=1]").find(".MLT_ShrinkSign").hide();
    }
    $(obj).find(".MLT_ExtendSign").show();
    $(obj).find(".MLT_ShrinkSign").hide();
    }

    //选择项
    function checkItems(obj, checked) {
    var rel = $(obj).attr("rel");
    if (rel != undefined && rel.length > 0) {
    if (checked) {
    $(obj).siblings("div[parent=" + rel + "]").each(function () {
    $(this).find("input[type=checkbox]").attr("checked", "checked");
    checkItems(this, checked);
    });
    }
    else {
    $(obj).siblings("div[parent=" + rel + "]").each(function () {
    $(this).find("input[type=checkbox]").removeAttr("checked");
    checkItems(this, checked);
    });
    }
    }
    else {
    if (checked) {
    $(obj).parent().find("input[type=checkbox]").attr("checked", "checked");
    }
    else {
    $(obj).parent().find("input[type=checkbox]").removeAttr("checked");
    }
    }
    }
    </script>
    <style type="text/css">
    .MLT_Panel
    {
    white-space: nowrap;
    overflow: auto;
    }

    .MLT_Item
    {
    font-size: 12px;
    line-height: 20px;
    cursor: pointer;
    }

    .MLT_Item_hover
    {
    background-color: rgb(167, 205, 240);
    }

    .MLT_Item span
    {
    line-height: 20px;
    display: inline-block;
    }

    .MLT_Checkbox
    {
    position: relative;
    12px;
    height: 12px;
    margin: 0 2px;
    bottom: 2px;
    }

    .MLT_ExtendSign, .MLT_ShrinkSign, .MLT_ExtendSignPlaceholder
    {
    font-family: "宋体";
    18px;
    text-align: center;
    }
    </style>

    示例:

    使用原数据:

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

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

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

  • 相关阅读:
    自然语言交流系统 phxnet团队 创新实训 项目博客 (十一)
    install ubuntu on Android mobile phone
    Mac OS, Mac OSX 与Darwin
    About darwin OS
    自然语言交流系统 phxnet团队 创新实训 项目博客 (十)
    Linux下编译安装qemu和libvirt
    libvirt(virsh命令总结)
    深入浅出 kvm qemu libvirt
    自然语言交流系统 phxnet团队 创新实训 项目博客 (九)
    自然语言交流系统 phxnet团队 创新实训 项目博客 (八)
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/3227112.html
Copyright © 2011-2022 走看看