本文共 23128 字,大约阅读时间需要 77 分钟。
FineUI开源版是没有树表格的,但是又需要,怎么办呢?在博客园看到一位大大的文章
http://www.cnblogs.com/shiworkyue/p/4211002.html
然后参考,不知道为什么这位大大的代码我运行不了,有问题,然后自己修改了下,逻辑什么的各位可以前往这个大大的博客看,下面放上代码
FineUI的Grid.cs代码
添加的代码
1 #region hzh modify 2 ///3 /// 是否启用树(扩展) 4 /// 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 ///26 /// 是否展开树(扩展) 27 /// 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 ///48 /// 树节点列名(扩展) 49 /// 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 ///67 /// 主键ID(扩展) 68 /// 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 ///85 /// 父节点列名(扩展) 86 /// 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 ///104 /// 得到当然行的层级(扩展)105 /// 106 /// 当前行107 /// 行数据集108 ///层级 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 //如果过是第第一级就是0117 if (row.Values[ParentIDindex].ToString() == "" || row.Values[ParentIDindex].ToString() == "0")118 {119 return lub;120 }121 else122 {123 foreach (GridRow gr in Rows)124 {125 //如果有父级126 if (gr.Values[IDindex].ToString() == row.Values[ParentIDindex].ToString())127 {128 //层级加1129 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 ListInsertRowToList(List toList, List 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 /// 182 /// 对rows进行重新排序(扩展)183 /// 184 private void SortTreeRows()185 {186 ListsourceRows = new List ();187 foreach (GridRow row in Rows)188 {189 sourceRows.Add(row);190 }191 Rows.Clear();192 193 List toList = new List ();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 /// 218 /// 给树赋值(扩展)219 /// 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 else243 {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] = "" + row.Values[1];252 }253 }254 }255 }256 }257 258 ///
259 /// 得到下级行号260 /// 261 /// 本节点262 /// 集合263 ///集合以,隔开 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 ///281 /// 得到所有子类行号282 /// 283 /// 本节点284 /// 集合285 /// 集合以,隔开286 ///集合以,隔开 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 ///301 /// 点击事件只给有子集的点击事件(扩展)302 /// 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 ///321 /// 移除的数据(扩展)322 /// 323 public ListMoveIndex324 {325 get326 {327 object obj = ViewState["MoveIndex"];328 return obj == null ? new List () : obj as List ;329 }330 set331 {332 333 ViewState["MoveIndex"] = value;334 }335 }336 337 // private static List _RowCollapsed;//展开集合338 /// 339 /// 展开集合(扩展)340 /// 341 public ListRowCollapsed342 {343 get344 {345 object obj = ViewState["RowCollapsed"];346 return obj == null ? new List () : obj as List ;347 }348 set349 {350 351 ViewState["RowCollapsed"] = value;352 }353 }354 355 /// 356 /// 第一次显示数方法(扩展)357 /// 358 private void ShowTree()359 {360 //初始化树361 if (EnableTree)362 {363 if (!ExpandAll)364 {365 ListlstMove = new List ();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变成1379 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 else409 {410 List _RowCollapsed = new List ();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 /// 429 /// 点击树事件(扩展)430 /// 431 /// 点击的节点(行号)432 public void DoTreeClick(string treenode)433 {434 if (EnableTree)435 {436 StringBuilder sb = new StringBuilder();437 List_MoveIndex = MoveIndex;438 List _RowCollapsed = RowCollapsed;439 //集合440 if (_RowCollapsed == null)441 {442 _RowCollapsed = new List ();443 }444 //每次点击更改集合,移出和新增445 if (_RowCollapsed.Contains(treenode))446 {447 _RowCollapsed.Remove(treenode);448 string strids = string.Empty;449 GetAllNextIndex(int.Parse(treenode), Rows, ref strids);450 if (!string.IsNullOrEmpty(strids.Trim()))451 {452 string[] ids = strids.Split(',');453 foreach (string item in ids)454 {455 _RowCollapsed.Remove(item);456 if (!_MoveIndex.Contains(item))457 _MoveIndex.Add(item);458 }459 }460 }461 else462 {463 if (!_RowCollapsed.Contains(treenode))464 _RowCollapsed.Add(treenode);465 string strids = GetNextIndex(Rows[int.Parse(treenode)], Rows);466 if (!string.IsNullOrEmpty(strids.Trim()))467 {468 string[] ids = strids.Split(',');469 foreach (string item in ids)470 {471 _MoveIndex.Remove(item);472 }473 }474 }475 476 int PIDindex = FindColumn(TreeDataParentIDField).ColumnIndex;477 int IDindex = FindColumn(TreeDataIDField).ColumnIndex;478 479 if (_MoveIndex.Count >= 2)480 {481 _MoveIndex.Sort(delegate(string str1, string str2) { return int.Parse(str2 == "" ? "0" : str2) - int.Parse(str1 == "" ? "0" : str1); });482 }483 string strMoveIndex = string.Empty;484 foreach (string ss in _MoveIndex)485 {486 strMoveIndex += strMoveIndex == "" ? ss : "," + ss;487 }488 489 RowCollapsed = _RowCollapsed;490 MoveIndex = _MoveIndex;491 492 if (strMoveIndex != null)493 {494 string js = ""495 + "var store =" + XID + ".getStore();"496 + "var rows = [" + strMoveIndex + "];"497 + "Ext.Array.each(rows, function (rowIndex, index) {"498 + " store.removeAt(rowIndex);"499 + "});"500 //刷新行号,(重要)501 + XID + ".view.refresh();";502 503 //string js = ""504 // + "var store =F('" + ClientID + "').getStore();"505 // + "var rows = [" + moveindex + "];"506 // + "Ext.Array.each(rows, function (rowIndex, index) {"507 // + " store.removeAt(rowIndex);"508 // + "});"509 510 // + "F('" + ClientID + "').view.refresh();";511 512 sb.Append("F('" + ClientID + "').f_loadData();");513 sb.Append(js);514 515 }516 517 foreach (string item in RowCollapsed)518 {519 string imgid = ClientID + "_tree_icon_" + item;520 sb.Append( "$(\"#" + imgid + "\").attr(\"src\",\"" + IconHelper.GetResolvedIconUrl(FineUI.Icon.ControlRemoveBlue) + "\");");521 }522 523 PageContext.RegisterStartupScript(sb.ToString());524 TreeClick();525 }526 527 528 }529 /// 530 /// 循环子集(扩展)531 /// 532 /// 533 /// 534 private void DoNextTreeClick(string treeindex, ref Listmovelist, bool Collapsed)535 {536 if (EnableTree)537 {538 StringBuilder sb = new StringBuilder();539 int PIDindex = FindColumn(TreeDataParentIDField).ColumnIndex;540 int IDindex = FindColumn(TreeDataIDField).ColumnIndex;541 //得到下一菜单542 string nextindex = GetNextIndex(Rows[Convert.ToInt32(treeindex)], Rows);543 if (nextindex != "")544 {545 string[] s = nextindex.Split(',');546 for (int i = 0; i < s.Length; i++)547 {548 GridRow dr = Rows[Convert.ToInt32(s[i])];549 string rowindex = dr.RowIndex.ToString();550 //展开551 if (movelist.Contains(rowindex) && Collapsed)552 {553 movelist.Remove(rowindex);554 }555 //收起556 if (!Collapsed && !movelist.Contains(rowindex))557 {558 movelist.Add(rowindex);559 }560 //展开子集在展开集合中则执行该子集的展开561 if (Collapsed && RowCollapsed.Contains(rowindex))562 {563 DoNextTreeClick(rowindex, ref movelist, true);564 }565 }566 }567 }568 }569 #endregion
修改的代码(主要是修改AfterDataBind方法)
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 #endregion11 if (!IsDatabasePaging)12 {13 // 如果不是数据库分页,则每次DataBind都要更新RecordCount的值14 // 数据库分页的话,RecordCount需要用户显式的赋值15 RecordCount = recordCount;16 }17 18 19 // 在所有行都绑定结束后,需要检查模拟树显示的列,并重新计算当前列的内容(在列内容前加上树分隔符)20 // 1.查找需要模拟树显示的列21 BaseField simulateTreeColumn = null;22 foreach (GridColumn gridColumn in AllColumns)23 {24 BaseField column = gridColumn as BaseField;25 if (column != null && !String.IsNullOrEmpty(column.DataSimulateTreeLevelField))26 {27 simulateTreeColumn = column;28 break;29 }30 }31 #region hzh modify32 if (EnableTree)33 {34 if (!string.IsNullOrEmpty(TreeName))35 {36 simulateTreeColumn = FindColumn(TreeName) as BaseField;37 }38 }39 #endregion40 41 // 2.如果找到这样的列42 if (simulateTreeColumn != null)43 {44 ListsilumateTree = new List ();45 46 // 存在需要模拟树显示的列47 for (int rowIndex = 0, rowCount = Rows.Count; rowIndex < rowCount; rowIndex++)48 {49 GridRow row = Rows[rowIndex];50 int level = 0;51 #region hzh modify52 if (EnableTree)53 {54 level = GetLevelNub(row, Rows) - 1;55 }56 else57 {58 object treeLevelObj = row.GetPropertyValue(simulateTreeColumn.DataSimulateTreeLevelField);59 if (treeLevelObj != null && treeLevelObj != DBNull.Value)60 {61 level = Convert.ToInt32(treeLevelObj);62 }63 }64 #endregion65 object content = row.Values[simulateTreeColumn.ColumnIndex];66 67 SimulateTreeNode node = new SimulateTreeNode();68 node.Text = content.ToString();69 node.Level = level;70 node.HasLittleBrother = false;71 node.ParentNode = null;72 silumateTree.Add(node);73 }74 75 // 计算树76 SimulateTreeHeper treeHelper = new SimulateTreeHeper();77 treeHelper.ResolveSimulateTree(silumateTree, true);78 79 // 赋值80 for (int rowIndex = 0, rowCount = Rows.Count; rowIndex < rowCount; rowIndex++)81 {82 Rows[rowIndex].Values[simulateTreeColumn.ColumnIndex] = silumateTree[rowIndex].Text;83 }84 }85 86 }
有标记“hzh modify”就是我修改和添加的
然后看一下测试页面的代码
页面代码:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="TestPage.aspx.cs" Inherits="FineUI.Examples.TestPage" %>
后台代码:
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 DataTable dt = new DataTable(); 16 dt.Columns.Add("name", typeof(string)); 17 dt.Columns.Add("id", typeof(int)); 18 dt.Columns.Add("topID", typeof(string)); 19 dt.Columns.Add("levelcode", typeof(string)); 20 dt.Columns.Add("levelnub", typeof(int)); 21 dt.Columns.Add("subitem", typeof(bool)); 22 dt.Columns.Add("url", typeof(string)); 23 24 DataRow dr1 = dt.NewRow(); 25 dr1[0] = "首页"; 26 dr1[1] = 1; 27 dr1[2] = 0; 28 dr1[3] = "0001"; 29 dr1[4] =0; 30 dr1[5] = false; 31 dr1[6] = "adfsdfds"; 32 dt.Rows.Add(dr1); 33 34 DataRow dr2 = dt.NewRow(); 35 dr2[0] = "测试页"; 36 dr2[1] = 2; 37 dr2[2] = 0; 38 dr2[3] = "0002"; 39 dr2[4] = 0; 40 dr2[5] = false; 41 dr2[6] = "adfsdfds"; 42 dt.Rows.Add(dr2); 43 44 //==================== 45 46 DataRow dr11 = dt.NewRow(); 47 dr11[0] = "首页下级1"; 48 dr11[1] = 3; 49 dr11[2] = 1; 50 dr11[3] = "00010001"; 51 dr11[4] = 1; 52 dr11[5] = true; 53 dr11[6] = "adfsdfds"; 54 dt.Rows.Add(dr11); 55 56 DataRow dr12 = dt.NewRow(); 57 dr12[0] = "首页下级2"; 58 dr12[1] = 4; 59 dr12[2] = 1; 60 dr12[3] = "00010002"; 61 dr12[4] = 1; 62 dr12[5] = true; 63 dr12[6] = "adfsdfds"; 64 dt.Rows.Add(dr12); 65 66 DataRow dr13 = dt.NewRow(); 67 dr13[0] = "首页下级3"; 68 dr13[1] = 5; 69 dr13[2] = 1; 70 dt.Rows.Add(dr13); 71 72 //======================== 73 74 75 DataRow dr21 = dt.NewRow(); 76 dr21[0] = "测试页下级1"; 77 dr21[1] = 6; 78 dr21[2] = 2; 79 dr21[3] = "00020001"; 80 dr21[4] = 1; 81 dr21[5] = true; 82 dr21[6] = "adfsdfds"; 83 dt.Rows.Add(dr21); 84 85 DataRow dr22 = dt.NewRow(); 86 dr22[0] = "测试页下级2"; 87 dr22[1] = 7; 88 dr22[2] = 2; 89 dr22[3] = "00020002"; 90 dr22[4] = 1; 91 dr22[5] = true; 92 dr22[6] = "adfsdfds"; 93 dt.Rows.Add(dr22); 94 95 96 DataRow dr221 = dt.NewRow(); 97 dr221[0] = "测试页下下级1"; 98 dr221[1] = 8; 99 dr221[2] = 7;100 dr221[3] = "00020002001";101 dr221[4] = 2;102 dr221[5] = true;103 dr221[6] = "adfsdfds";104 dt.Rows.Add(dr221);105 106 DataRow dr00 = dt.NewRow();107 dr00[0] = "00测试";108 dr00[1] = 8;109 dr00[2] = 14;110 dr00[3] = "00020002001";111 dr00[4] = 2;112 dr00[5] = true;113 dr00[6] = "adfsdfds";114 dt.Rows.Add(dr00);115 116 Grid1.DataSource = dt;117 Grid1.DataBind();118 }119 120 protected void PageManager_CustomEvent(object sender, CustomEventArgs e)121 {122 if (e.EventArgument.IndexOf("GridTreeClick_") >= 0)123 {124 string rowindex = e.EventArgument.ToString().Split('_')[1];125 Grid1.DoTreeClick(rowindex);126 }127 }128 }129 }
然后就是效果图了
再次感谢