很久都没有写点什么出来分享了,最近在做多级树的时候,发现来来回回写过很多遍,于是封装成用户控件,以方便日后重复使用.
首先上效果:
我们看到以上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 = " "; 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='width:{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 }