FineUI开源版之TreeGrid(修改)
上篇文章中做了简单实现,但是还是有bug的,还需要在外面写事件的处理,今天又进行修改了。
下面放出代码,同样的 hzh modify标记的就是我进行修改的地方
grid.cs 添加代码
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #region hzh modify 2 /// <summary> 3 /// 是否启用树(扩展) 4 /// </summary> 5 [Category(CategoryName.OPTIONS)] 6 [DefaultValue(null)] 7 [Description("是否启用树(扩展)")] 8 public bool EnableTree 9 { 10 get 11 { 12 object obj = FState["EnableTree"]; 13 return obj == null ? false : (bool)obj; 14 } 15 set 16 { 17 FState["EnableTree"] = value; 18 if (value) 19 { 20 EnableRowClickEvent = false; 21 } 22 } 23 } 24 25 /// <summary> 26 /// 是否展开树(扩展) 27 /// </summary> 28 [Category(CategoryName.OPTIONS)] 29 [DefaultValue(null)] 30 [Description("是否展开树(扩展)")] 31 public bool ExpandAll 32 { 33 get 34 { 35 object obj = FState["ExpandAll"]; 36 return obj == null ? true : (bool)obj; 37 } 38 set 39 { 40 FState["ExpandAll"] = value; 41 if (value) 42 { 43 EnableRowClickEvent = false; 44 } 45 } 46 } 47 /// <summary> 48 /// 树节点列名(扩展) 49 /// </summary> 50 [Category(CategoryName.OPTIONS)] 51 [DefaultValue(null)] 52 [Description("树节点列名(扩展)")] 53 public string TreeName 54 { 55 get 56 { 57 object obj = FState["TreeName"]; 58 return obj == null ? "" : (string)obj; 59 } 60 set 61 { 62 FState["TreeName"] = value; 63 } 64 } 65 66 /// <summary> 67 /// 主键ID(扩展) 68 /// </summary> 69 [Category(CategoryName.OPTIONS)] 70 [DefaultValue(null)] 71 [Description("主键ID(扩展)")] 72 public string TreeDataIDField 73 { 74 get 75 { 76 object obj = FState["TreeDataIDField"]; 77 return obj == null ? "" : (string)obj; 78 } 79 set 80 { 81 FState["TreeDataIDField"] = value; 82 } 83 } 84 /// <summary> 85 /// 父节点列名(扩展) 86 /// </summary> 87 [Category(CategoryName.OPTIONS)] 88 [DefaultValue(null)] 89 [Description("父节点列名(扩展)")] 90 public string TreeDataParentIDField 91 { 92 get 93 { 94 object obj = FState["TreeDataParentIDField"]; 95 return obj == null ? "" : (string)obj; 96 } 97 set 98 { 99 FState["TreeDataParentIDField"] = value; 100 } 101 } 102 103 /// <summary> 104 /// 得到当然行的层级(扩展) 105 /// </summary> 106 /// <param name="row">当前行</param> 107 /// <param name="Rows">行数据集</param> 108 /// <returns>层级</returns> 109 private int GetLevelNub(GridRow row, GridRowCollection Rows) 110 { 111 int lub = 0; 112 //ID所在列 113 int IDindex = FindColumn(TreeDataIDField).ColumnIndex; 114 //父ID所在列 115 int ParentIDindex = FindColumn(TreeDataParentIDField).ColumnIndex; 116 //如果过是第第一级就是0 117 if (row.Values[ParentIDindex].ToString() == "" || row.Values[ParentIDindex].ToString() == "0") 118 { 119 return lub; 120 } 121 else 122 { 123 foreach (GridRow gr in Rows) 124 { 125 //如果有父级 126 if (gr.Values[IDindex].ToString() == row.Values[ParentIDindex].ToString()) 127 { 128 //层级加1 129 lub++; 130 //查看父级的父级 131 int nub = GetLevelNub(gr, Rows); 132 lub += nub == 0 ? 1 : nub; 133 } 134 } 135 } 136 return lub; 137 } 138 139 140 private List<GridRow> InsertRowToList(List<GridRow> toList, List<GridRow> sourceRows, int idindex, int pridindex) 141 { 142 for (int i = toList.Count - 1; i >= 0; i--) 143 { 144 GridRow torow = toList[i]; 145 bool ismodify = false; 146 if (sourceRows == null || sourceRows.Count <= 0) 147 return toList; 148 for (int j = sourceRows.Count - 1; j >= 0; j--) 149 { 150 GridRow baserow = sourceRows[j]; 151 if (baserow.Values[pridindex].ToString() != "" && baserow.Values[pridindex].ToString() == torow.Values[idindex].ToString()) 152 { 153 toList.Insert(i + 1, baserow); 154 sourceRows.RemoveAt(j); 155 ismodify = true; 156 } 157 } 158 if (sourceRows.Count <= 0) 159 { 160 sourceRows.Clear(); 161 sourceRows = null; 162 return toList; 163 } 164 if (ismodify == false) 165 { 166 if (sourceRows.Count > 0) 167 { 168 foreach (GridRow item in sourceRows) 169 { 170 toList.Add(item); 171 } 172 sourceRows.Clear(); 173 sourceRows = null; 174 } 175 return toList; 176 } 177 } 178 return InsertRowToList(toList, sourceRows, idindex, pridindex); 179 } 180 181 /// <summary> 182 /// 对rows进行重新排序(扩展) 183 /// </summary> 184 private void SortTreeRows() 185 { 186 List<GridRow> sourceRows = new List<GridRow>(); 187 foreach (GridRow row in Rows) 188 { 189 sourceRows.Add(row); 190 } 191 Rows.Clear(); 192 193 List<GridRow> toList = new List<GridRow>(); 194 195 int pidindex = FindColumn(TreeDataParentIDField).ColumnIndex; 196 int idindex = FindColumn(TreeDataIDField).ColumnIndex; 197 for (int i = sourceRows.Count - 1; i >= 0; i--) 198 { 199 GridRow row = sourceRows[i]; 200 if (row.Values[pidindex].ToString() == "" || row.Values[pidindex].ToString() == "0") 201 { 202 toList.Insert(0, row); 203 sourceRows.RemoveAt(i); 204 } 205 } 206 207 toList = InsertRowToList(toList, sourceRows, idindex, pidindex); 208 toList.ForEach(p => Rows.Add(p)); 209 for (int i = 0; i < Rows.Count; i++) 210 { 211 Rows[i].RowIndex = i; 212 } 213 toList.Clear(); 214 toList = null; 215 } 216 217 /// <summary> 218 /// 给树赋值(扩展) 219 /// </summary> 220 private void SetValueTree() 221 { 222 if (EnableTree) 223 { 224 foreach (GridRow row in Rows) 225 { 226 //下级行数 227 string Nextindex = GetNextIndex(row, Rows); 228 //默认图标 229 Icon iconindex = FineUI.Icon.ControlBlankBlue; 230 // string iconname = "page.png"; 231 //图片ID,点击用,绑定事件 232 string imgid = ClientID + "_tree_icon_" + row.RowIndex; 233 //父节点图标 234 if (Nextindex != "") 235 { 236 if (ExpandAll) 237 { 238 iconindex = FineUI.Icon.ControlRemoveBlue; 239 //设置展开行 240 RowCollapsed.Add(row.RowIndex.ToString()); 241 } 242 else 243 { 244 iconindex = FineUI.Icon.ControlAddBlue; 245 } 246 // iconname = "folder.png"; 247 248 //加入图标和ID,注意加过的就不加了 249 if (row.Values[FindColumn(TreeName).ColumnIndex].ToString().IndexOf(ClientID + "_tree_icon_") < 0) 250 { 251 row.Values[FindColumn(TreeName).ColumnIndex] = "<img id=\"" + imgid + "\" src=\"" + IconHelper.GetResolvedIconUrl(iconindex) + "\" width=\"16\" height=\"16\" style=\"margin-top:-5px;margin-bottom:-2px;cursor: pointer\"/>" + row.Values[1]; 252 } 253 } 254 } 255 } 256 } 257 258 /// <summary> 259 /// 得到下级行号 260 /// </summary> 261 /// <param name="row">本节点</param> 262 /// <param name="Rows">集合</param> 263 /// <returns>集合以,隔开</returns> 264 private string GetNextIndex(GridRow row, GridRowCollection Rows) 265 { 266 string topindex = ""; 267 int pridindex = FindColumn(TreeDataParentIDField).ColumnIndex; 268 int idindex = FindColumn(TreeDataIDField).ColumnIndex; 269 foreach (GridRow gr in Rows) 270 { 271 //父ID等于本ID添加到集合 272 if (gr.Values[pridindex].ToString() != "" && gr.Values[pridindex].ToString() == row.Values[idindex].ToString()) 273 { 274 topindex += topindex == "" ? gr.RowIndex.ToString() : "," + gr.RowIndex.ToString(); 275 } 276 } 277 return topindex; 278 } 279 280 /// <summary> 281 /// 得到所有子类行号 282 /// </summary> 283 /// <param name="row">本节点</param> 284 /// <param name="Rows">集合</param> 285 /// <param name="strIndexs">集合以,隔开</param> 286 /// <returns>集合以,隔开</returns> 287 private void GetAllNextIndex(int rowindex, GridRowCollection Rows, ref string strIndexs) 288 { 289 string index = GetNextIndex(Rows[rowindex], Rows); 290 if (string.IsNullOrEmpty(index.Trim())) 291 return; 292 strIndexs = string.IsNullOrEmpty(strIndexs) ? index : (strIndexs + "," + index); 293 string[] indexs = index.Split(','); 294 foreach (string item in indexs) 295 { 296 GetAllNextIndex(int.Parse(item), Rows, ref strIndexs); 297 } 298 } 299 300 /// <summary> 301 /// 点击事件只给有子集的点击事件(扩展) 302 /// </summary> 303 private void TreeClick() 304 { 305 StringBuilder sbx = new StringBuilder(); 306 foreach (GridRow row in Rows) 307 { 308 //有下级菜单才绑定事件 309 string Nextindex = GetNextIndex(row, Rows); 310 if (Nextindex != "") 311 { 312 string imgid = ClientID + "_tree_icon_" + row.RowIndex; 313 sbx.Append("$('#" + imgid + "').click(function(){F.customEvent(\"GridTreeClick_" + row.RowIndex + "\");});"); 314 } 315 } 316 PageContext.RegisterStartupScript(sbx.ToString()); 317 } 318 319 // private static string _moveindex;//移除的数据 320 /// <summary> 321 /// 移除的数据(扩展) 322 /// </summary> 323 public List<string> MoveIndex 324 { 325 get 326 { 327 object obj = ViewState["MoveIndex"]; 328 return obj == null ? new List<string>() : obj as List<string>; 329 } 330 set 331 { 332 333 ViewState["MoveIndex"] = value; 334 } 335 } 336 337 // private static List<string> _RowCollapsed;//展开集合 338 /// <summary> 339 /// 展开集合(扩展) 340 /// </summary> 341 public List<string> RowCollapsed 342 { 343 get 344 { 345 object obj = ViewState["RowCollapsed"]; 346 return obj == null ? new List<string>() : obj as List<string>; 347 } 348 set 349 { 350 351 ViewState["RowCollapsed"] = value; 352 } 353 } 354 355 /// <summary> 356 /// 第一次显示数方法(扩展) 357 /// </summary> 358 private void ShowTree() 359 { 360 //初始化树 361 if (EnableTree) 362 { 363 if (!ExpandAll) 364 { 365 List<string> lstMove = new List<string>(); 366 //循环行 367 foreach (GridRow row in Rows) 368 { 369 //得到层级 370 int lub = GetLevelNub(row, Rows); 371 if (lub != 0) 372 { 373 //子集删除 374 if (!lstMove.Contains(row.RowIndex.ToString())) 375 lstMove.Add(row.RowIndex.ToString()); 376 } 377 } 378 //排序(重要) 从大到小排序,不排序会删除1后造成2变成1 379 lstMove.Sort(delegate(string str1, string str2) { return int.Parse(str2) - int.Parse(str1); }); 380 if (MoveIndex == null || MoveIndex.Count == 0) 381 MoveIndex = lstMove; 382 string strMoveIndex = string.Empty; 383 foreach (string item in lstMove) 384 { 385 strMoveIndex += string.IsNullOrEmpty(strMoveIndex) ? item : ("," + item); 386 } 387 388 string js = string.Empty; 389 if (!string.IsNullOrEmpty(strMoveIndex)) 390 { 391 //放入缓存记录已经消除的行 392 393 js = "" 394 + "var store =" + XID + ".getStore();" 395 + "var rows = [" + strMoveIndex + "];" 396 + "Ext.Array.each(rows, function (rowIndex, index) {" 397 + " store.removeAt(rowIndex);" 398 + "});" 399 //刷新行号,(重要) 400 + XID + ".view.refresh();"; 401 402 } 403 if (!string.IsNullOrEmpty(js)) 404 PageContext.RegisterStartupScript(js); 405 //绑定树点击事件 406 TreeClick(); 407 } 408 else 409 { 410 List<string> _RowCollapsed = new List<string>(); 411 //循环行 412 foreach (GridRow row in Rows) 413 { 414 //得到层级 415 if (!string.IsNullOrEmpty(GetNextIndex(row, Rows))) 416 { 417 if (!_RowCollapsed.Contains(row.RowIndex.ToString())) 418 _RowCollapsed.Add(row.RowIndex.ToString()); 419 } 420 } 421 RowCollapsed = _RowCollapsed; 422 //绑定树点击事件 423 TreeClick(); 424 } 425 } 426 } 427 428 /// <summary> 429 /// 点击树事件(扩展) 430 /// </summary> 431 /// <param name="treenode">点击的节点(行号)</param> 432 public void DoTreeClick(string treenode) 433 { 434 if (EnableTree) 435 { 436 437 string strIconJs = string.Empty; 438 StringBuilder sb = new StringBuilder(); 439 string[] strsmove = new string[MoveIndex.Count]; 440 MoveIndex.CopyTo(strsmove); 441 List<string> _MoveIndex = new List<string>(strsmove); 442 string[] strscoll = new string[RowCollapsed.Count]; 443 RowCollapsed.CopyTo(strscoll); 444 List<string> _RowCollapsed = new List<string>(strscoll); 445 // ShowTree(); 446 //集合 447 if (_RowCollapsed == null) 448 { 449 _RowCollapsed = new List<string>(); 450 } 451 //每次点击更改集合,移出和新增 452 if (_RowCollapsed.Contains(treenode)) 453 { 454 _RowCollapsed.Remove(treenode); 455 string strids = string.Empty; 456 GetAllNextIndex(int.Parse(treenode), Rows, ref strids); 457 if (!string.IsNullOrEmpty(strids.Trim())) 458 { 459 string[] ids = strids.Split(','); 460 foreach (string item in ids) 461 { 462 _RowCollapsed.Remove(item); 463 string imgid = ClientID + "_tree_icon_" + item; 464 strIconJs += "$(\"#" + imgid + "\").attr(\"src\",\"" + IconHelper.GetResolvedIconUrl(FineUI.Icon.ControlAddBlue) + "\");"; 465 if (!_MoveIndex.Contains(item)) 466 _MoveIndex.Add(item); 467 } 468 } 469 } 470 else 471 { 472 if (!_RowCollapsed.Contains(treenode)) 473 _RowCollapsed.Add(treenode); 474 string strids = GetNextIndex(Rows[int.Parse(treenode)], Rows); 475 if (!string.IsNullOrEmpty(strids.Trim())) 476 { 477 string[] ids = strids.Split(','); 478 foreach (string item in ids) 479 { 480 _MoveIndex.Remove(item); 481 } 482 } 483 } 484 485 int PIDindex = FindColumn(TreeDataParentIDField).ColumnIndex; 486 int IDindex = FindColumn(TreeDataIDField).ColumnIndex; 487 488 if (_MoveIndex.Count >= 2) 489 { 490 _MoveIndex.Sort(delegate(string str1, string str2) { return int.Parse(str2 == "" ? "0" : str2) - int.Parse(str1 == "" ? "0" : str1); }); 491 } 492 string strMoveIndex = string.Empty; 493 foreach (string ss in _MoveIndex) 494 { 495 strMoveIndex += strMoveIndex == "" ? ss : "," + ss; 496 } 497 498 RowCollapsed = _RowCollapsed; 499 MoveIndex = _MoveIndex; 500 501 if (strMoveIndex != null) 502 { 503 string js = "" 504 //+"F.ready(function(){" 505 + "var store =F('" + ClientID + "').getStore();" 506 + "var rows = [" + strMoveIndex + "];" 507 + "Ext.Array.each(rows, function (rowIndex, index) {" 508 + " store.removeAt(rowIndex);" 509 + "});" 510 //+ XID + ".f_loadData();" 511 + "F('" + ClientID + "').view.refresh();"; 512 513 sb.Append("F('" + ClientID + "').f_loadData();"); 514 sb.Append(js); 515 516 } 517 sb.Append(strIconJs); 518 foreach (string item in RowCollapsed) 519 { 520 string imgid = ClientID + "_tree_icon_" + item; 521 sb.Append("$(\"#" + imgid + "\").attr(\"src\",\"" + IconHelper.GetResolvedIconUrl(FineUI.Icon.ControlRemoveBlue) + "\");"); 522 } 523 524 PageContext.RegisterStartupScript(sb.ToString()); 525 TreeClick(); 526 } 527 528 529 } 530 /// <summary> 531 /// 循环子集(扩展) 532 /// </summary> 533 /// <param name="treeindex"></param> 534 /// <param name="movelist"></param> 535 private void DoNextTreeClick(string treeindex, ref List<string> movelist, bool Collapsed) 536 { 537 if (EnableTree) 538 { 539 StringBuilder sb = new StringBuilder(); 540 int PIDindex = FindColumn(TreeDataParentIDField).ColumnIndex; 541 int IDindex = FindColumn(TreeDataIDField).ColumnIndex; 542 //得到下一菜单 543 string nextindex = GetNextIndex(Rows[Convert.ToInt32(treeindex)], Rows); 544 if (nextindex != "") 545 { 546 string[] s = nextindex.Split(','); 547 for (int i = 0; i < s.Length; i++) 548 { 549 GridRow dr = Rows[Convert.ToInt32(s[i])]; 550 string rowindex = dr.RowIndex.ToString(); 551 //展开 552 if (movelist.Contains(rowindex) && Collapsed) 553 { 554 movelist.Remove(rowindex); 555 } 556 //收起 557 if (!Collapsed && !movelist.Contains(rowindex)) 558 { 559 movelist.Add(rowindex); 560 } 561 //展开子集在展开集合中则执行该子集的展开 562 if (Collapsed && RowCollapsed.Contains(rowindex)) 563 { 564 DoNextTreeClick(rowindex, ref movelist, true); 565 } 566 } 567 } 568 } 569 } 570 571 /// <summary> 572 /// 处理自定义事件(扩展) 573 /// </summary> 574 /// <param name="e"></param> 575 public void CheckCustomEventArgs(CustomEventArgs e) 576 { 577 if (EnableTree && !string.IsNullOrEmpty(TreeName) && !string.IsNullOrEmpty(TreeDataIDField) && !string.IsNullOrEmpty(TreeDataParentIDField)) 578 { 579 if (e.EventArgument.IndexOf("GridTreeClick_") >= 0) 580 { 581 string rowindex = e.EventArgument.ToString().Split('_')[1]; 582 DoTreeClick(rowindex); 583 } 584 } 585 } 586 587 #endregion
grid.cs 修改代码
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 private void AfterDataBind(int recordCount) 2 { 3 #region hzh modify 4 if (EnableTree && !string.IsNullOrEmpty(TreeName) && !string.IsNullOrEmpty(TreeDataIDField) && !string.IsNullOrEmpty(TreeDataParentIDField)) 5 { 6 SortTreeRows(); 7 SetValueTree(); 8 ShowTree(); 9 10 } 11 #endregion 12 if (!IsDatabasePaging) 13 { 14 // 如果不是数据库分页,则每次DataBind都要更新RecordCount的值 15 // 数据库分页的话,RecordCount需要用户显式的赋值 16 RecordCount = recordCount; 17 } 18 19 20 // 在所有行都绑定结束后,需要检查模拟树显示的列,并重新计算当前列的内容(在列内容前加上树分隔符) 21 // 1.查找需要模拟树显示的列 22 BaseField simulateTreeColumn = null; 23 foreach (GridColumn gridColumn in AllColumns) 24 { 25 BaseField column = gridColumn as BaseField; 26 if (column != null && !String.IsNullOrEmpty(column.DataSimulateTreeLevelField)) 27 { 28 simulateTreeColumn = column; 29 break; 30 } 31 } 32 #region hzh modify 33 if (EnableTree) 34 { 35 if (!string.IsNullOrEmpty(TreeName)) 36 { 37 simulateTreeColumn = FindColumn(TreeName) as BaseField; 38 } 39 } 40 #endregion 41 42 // 2.如果找到这样的列 43 if (simulateTreeColumn != null) 44 { 45 List<SimulateTreeNode> silumateTree = new List<SimulateTreeNode>(); 46 47 // 存在需要模拟树显示的列 48 for (int rowIndex = 0, rowCount = Rows.Count; rowIndex < rowCount; rowIndex++) 49 { 50 GridRow row = Rows[rowIndex]; 51 int level = 0; 52 #region hzh modify 53 if (EnableTree) 54 { 55 level = GetLevelNub(row, Rows) - 1; 56 } 57 else 58 { 59 object treeLevelObj = row.GetPropertyValue(simulateTreeColumn.DataSimulateTreeLevelField); 60 if (treeLevelObj != null && treeLevelObj != DBNull.Value) 61 { 62 level = Convert.ToInt32(treeLevelObj); 63 } 64 } 65 #endregion 66 object content = row.Values[simulateTreeColumn.ColumnIndex]; 67 68 SimulateTreeNode node = new SimulateTreeNode(); 69 node.Text = content.ToString(); 70 node.Level = level; 71 node.HasLittleBrother = false; 72 node.ParentNode = null; 73 silumateTree.Add(node); 74 } 75 76 // 计算树 77 SimulateTreeHeper treeHelper = new SimulateTreeHeper(); 78 treeHelper.ResolveSimulateTree(silumateTree, true); 79 80 // 赋值 81 for (int rowIndex = 0, rowCount = Rows.Count; rowIndex < rowCount; rowIndex++) 82 { 83 Rows[rowIndex].Values[simulateTreeColumn.ColumnIndex] = silumateTree[rowIndex].Text; 84 } 85 } 86 87 }
pagemanager.cs添加代码
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #region hzh modify 2 /// <summary> 3 /// 设置treegrid自定义事件 4 /// </summary> 5 /// <param name="e"></param> 6 private void SetCustomEventArgs(CustomEventArgs e) 7 { 8 if (!string.IsNullOrEmpty(TreeGridID)) 9 { 10 Grid grid = ControlUtil.FindControl(TreeGridID) as Grid; 11 grid.CheckCustomEventArgs(e); 12 } 13 } 14 /// <summary> 15 /// TreeGridID(扩展) 16 /// </summary> 17 [Category(CategoryName.OPTIONS)] 18 [DefaultValue(null)] 19 [Description("TreeGridID(扩展)")] 20 public string TreeGridID 21 { 22 get 23 { 24 object obj = FState["TreeGridID"]; 25 return obj == null ? "" : obj.ToString(); 26 } 27 set 28 { 29 FState["TreeGridID"] = value; 30 } 31 } 32 #endregion
pagemanager.cs修改代码
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 /// <summary> 2 /// 触发自定义事件 3 /// </summary> 4 /// <param name="e">事件参数</param> 5 protected virtual void OnCustomEvent(CustomEventArgs e) 6 { 7 #region hzh modify 8 SetCustomEventArgs(e); 9 #endregion 10 EventHandler<CustomEventArgs> handler = Events[_handlerKey] as EventHandler<CustomEventArgs>; 11 if (handler != null) 12 { 13 handler(this, e); 14 } 15 }
测试页面代码
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="TestPage.aspx.cs" Inherits="FineUI.Examples.TestPage" %> 2 3 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 4 <html xmlns="http://www.w3.org/1999/xhtml"> 5 <head runat="server"> 6 <title></title> 7 </head> 8 <body> 9 <form id="form1" runat="server"> 10 <f:PageManager ID="PageManager1" runat="server" TreeGridID="Grid1"/> 11 <f:Grid EnableCollapse="true" Width="800px" Height="400px" runat="server" DataKeyNames="Id,Name" 12 ID="Grid1" EnableTree="true" TreeName="name" TreeDataIDField="id" TreeDataParentIDField="topID" 13 ShowBorder="true" ShowHeader="true" Title="树表格" ExpandAll="false"> 14 <Columns> 15 <f:RowNumberField /> 16 <f:BoundField ColumnID="name" ExpandUnusedSpace="true" DataField="name" HeaderText="名称"> 17 </f:BoundField> 18 <f:BoundField ColumnID="id" DataField="id" Width="50px" HeaderText="ID"> 19 </f:BoundField> 20 <f:BoundField ColumnID="topID" DataField="topID" Width="50px" HeaderText="topID"> 21 </f:BoundField> 22 <f:BoundField DataField="levelcode" Width="100px" HeaderText="层级编号"> 23 </f:BoundField> 24 <f:BoundField ColumnID="levelnub" DataField="levelnub" Width="100px" HeaderText="层级数"> 25 </f:BoundField> 26 <f:BoundField DataField="subitem" Width="100px" HeaderText="是否为子菜单"> 27 </f:BoundField> 28 <f:BoundField DataField="url" Width="100px" HeaderText="地址"> 29 </f:BoundField> 30 </Columns> 31 </f:Grid> 32 </form> 33 <script src="./res/js/jquery.min.js"></script> 34 </body> 35 </html>
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 using System; 2 using System.Collections.Generic; 3 4 using System.Web; 5 using System.Web.UI; 6 using System.Web.UI.WebControls; 7 using System.Data; 8 9 namespace FineUI.Examples 10 { 11 public partial class TestPage : System.Web.UI.Page 12 { 13 protected void Page_Load(object sender, EventArgs e) 14 { 15 if (IsPostBack) 16 return; 17 DataTable dt = new DataTable(); 18 dt.Columns.Add("name", typeof(string)); 19 dt.Columns.Add("id", typeof(int)); 20 dt.Columns.Add("topID", typeof(string)); 21 dt.Columns.Add("levelcode", typeof(string)); 22 dt.Columns.Add("levelnub", typeof(int)); 23 dt.Columns.Add("subitem", typeof(bool)); 24 dt.Columns.Add("url", typeof(string)); 25 26 DataRow dr1 = dt.NewRow(); 27 dr1[0] = "首页"; 28 dr1[1] = 1; 29 dr1[2] = 0; 30 dr1[3] = "0001"; 31 dr1[4] =0; 32 dr1[5] = false; 33 dr1[6] = "adfsdfds"; 34 dt.Rows.Add(dr1); 35 36 DataRow dr2 = dt.NewRow(); 37 dr2[0] = "测试页"; 38 dr2[1] = 2; 39 dr2[2] = 0; 40 dr2[3] = "0002"; 41 dr2[4] = 0; 42 dr2[5] = false; 43 dr2[6] = "adfsdfds"; 44 dt.Rows.Add(dr2); 45 46 //==================== 47 48 DataRow dr11 = dt.NewRow(); 49 dr11[0] = "首页下级1"; 50 dr11[1] = 3; 51 dr11[2] = 1; 52 dr11[3] = "00010001"; 53 dr11[4] = 1; 54 dr11[5] = true; 55 dr11[6] = "adfsdfds"; 56 dt.Rows.Add(dr11); 57 58 DataRow dr12 = dt.NewRow(); 59 dr12[0] = "首页下级2"; 60 dr12[1] = 4; 61 dr12[2] = 1; 62 dr12[3] = "00010002"; 63 dr12[4] = 1; 64 dr12[5] = true; 65 dr12[6] = "adfsdfds"; 66 dt.Rows.Add(dr12); 67 68 DataRow dr13 = dt.NewRow(); 69 dr13[0] = "首页下级3"; 70 dr13[1] = 5; 71 dr13[2] = 1; 72 dt.Rows.Add(dr13); 73 74 //======================== 75 76 77 DataRow dr21 = dt.NewRow(); 78 dr21[0] = "测试页下级1"; 79 dr21[1] = 6; 80 dr21[2] = 2; 81 dr21[3] = "00020001"; 82 dr21[4] = 1; 83 dr21[5] = true; 84 dr21[6] = "adfsdfds"; 85 dt.Rows.Add(dr21); 86 87 DataRow dr22 = dt.NewRow(); 88 dr22[0] = "测试页下级2"; 89 dr22[1] = 7; 90 dr22[2] = 2; 91 dr22[3] = "00020002"; 92 dr22[4] = 1; 93 dr22[5] = true; 94 dr22[6] = "adfsdfds"; 95 dt.Rows.Add(dr22); 96 97 98 DataRow dr221 = dt.NewRow(); 99 dr221[0] = "测试页下下级1"; 100 dr221[1] = 8; 101 dr221[2] = 7; 102 dr221[3] = "00020002001"; 103 dr221[4] = 2; 104 dr221[5] = true; 105 dr221[6] = "adfsdfds"; 106 dt.Rows.Add(dr221); 107 108 DataRow dr00 = dt.NewRow(); 109 dr00[0] = "00测试"; 110 dr00[1] = 8; 111 dr00[2] = 14; 112 dr00[3] = "00020002001"; 113 dr00[4] = 2; 114 dr00[5] = true; 115 dr00[6] = "adfsdfds"; 116 dt.Rows.Add(dr00); 117 118 Grid1.DataSource = dt; 119 Grid1.DataBind(); 120 } 121 122 123 } 124 }
效果图:
作者:冰封一夏
出处:http://www.cnblogs.com/bfyx/
HZHControls官网:http://www.hzhcontrols.com
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,
且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
GitHub:https://github.com/kwwwvagaa/NetWinformControl
码云:https://gitee.com/kwwwvagaa/net_winform_custom_control.git