標籤:
1.加表徵圖和事件
上次已經通過DataSimulateTreeLevelField屬性控制了樹節點的顯示,不用看也知道就是給指定列資料前面加個表徵圖的HTML
可以在SimulateTreeHeper類裡看到實現方法,不多說了,原理就是迴圈行累加片就可以了,注意圖片的ID和樣式
/// <summary> /// 給樹賦值 /// </summary> private void SetValueTree() { if (EnableTree) { foreach (GridRow row in Rows) { //下級行數 string Nextindex = GetNextIndex(row, Rows); //預設表徵圖 string iconname = "page.png"; //圖片ID,點擊用,綁定事件 string imgid = ClientID+"_tree_icon_" + row.RowIndex; //父節點表徵圖 if (Nextindex != "") { iconname = "folder.png"; } //加入表徵圖和ID,注意加過的就不加了 if (row.Values[FindColumn(TreeName).ColumnIndex].ToString().IndexOf(ClientID+"_tree_icon_") < 0) { row.Values[FindColumn(TreeName).ColumnIndex] = "<img id=\"" + imgid + "\" src=\"..\\res\\icon\\" + iconname + "\" width=\"16\" height=\"16\" style=\"margin-top:-5px;margin-bottom:-2px;cursor: pointer\"/>" + row.Values[1]; } } } } /// <summary> /// 得到下級行號 /// </summary> /// <param name="row">本節點</param> /// <param name="Rows">集合</param> /// <returns>集合以,隔開</returns> private string GetNextIndex(GridRow row, GridRowCollection Rows) { string topindex = ""; int pridindex = FindColumn(TreeDataParentIDField).ColumnIndex; int idindex = FindColumn(TreeDataIDField).ColumnIndex; foreach (GridRow gr in Rows) { //父ID等於本ID添加到集合 if (gr.Values[pridindex].ToString() != "" && gr.Values[pridindex].ToString() == row.Values[idindex].ToString()) { topindex += topindex == "" ? gr.RowIndex.ToString() : "," + gr.RowIndex.ToString(); } } return topindex; }
這裡有個方法是得到下級的行號,這是個核心方法。在AfterDataBind裡加上就可以了
下面就是點擊方法,用JQ實現的,從後台輸出
/// <summary> /// 點擊事件只給有子集的點擊事件 /// </summary> private void TreeClick() { StringBuilder sbx = new StringBuilder(); foreach (GridRow row in Rows) { //有下級菜單才綁定事件 string Nextindex = GetNextIndex(row, Rows); if (Nextindex != "") { string imgid = ClientID + "_tree_icon_" + row.RowIndex; sbx.Append("$(‘#" + imgid + "‘).click(function(){F.customEvent(\"GridTreeClick_" + row.RowIndex + "\");});"); } } PageContext.RegisterStartupScript(sbx.ToString()); }
還是用到了F.customEvent方法回傳後台,其實可以用doPostBack方法直接在Grid.cs裡執行,但是考慮到會執行其他方法還是給放到頁面的cs檔案了,grid_tree.cs
protected void PageManager1_CustomEvent(object sender, CustomEventArgs e) { if (e.EventArgument.IndexOf("GridTreeClick_") >= 0) { string rowindex = e.EventArgument.ToString().Split(‘_‘)[1]; Grid1.DoTreeClick(rowindex); } }
可以看到DoTreeClick就是點擊樹表徵圖的方法,這個方法 實現收合和展開。2.實現展開和收合在DoTreeClick之前先要有第一次載入方法。首先要先定義一個參數,這個參數記錄應該刪除的行號,前面已經說是通過刪除行實現收合和展開的
private static string _moveindex;//移除的資料 /// <summary> /// 移除的資料 /// </summary> public static string moveindex { get { return _moveindex; } set { _moveindex = value; } }
可以看到這個參數是static的不會平白消失,FineUI控制屬性的Ajax回傳是在建構函式裡,
有興趣的可以研究下,我還沒太懂先寫一個第一次載入的方法,實現綁定了所有資料但只顯示第一層根節點。
/// <summary> /// 第一次顯示數方法 /// </summary> private void ShowTree() { //初始化樹 if (EnableTree) { List<string> movelist = new List<string>(); //迴圈行 foreach (GridRow row in Rows) { //得到層級 int lub = GetLevelNub(row, Rows); if (lub != 0) { //子集刪除 movelist.Add(row.RowIndex.ToString()); } } //排序(重要) 從大到小排序,不排序會刪除1後造成2變成1 movelist.Sort(delegate(string str1, string str2) { return int.Parse(str2) - int.Parse(str1); }); string MoveRowIndex = ""; foreach (string s in movelist) { MoveRowIndex += MoveRowIndex == "" ? s : "," + s; } if (MoveRowIndex != null) { //放入緩衝記錄已經消除的行 moveindex = MoveRowIndex; string js = "" + "var store =" + XID + ".getStore();" + "var rows = [" + MoveRowIndex + "];" + "Ext.Array.each(rows, function (rowIndex, index) {" + " store.removeAt(rowIndex);" + "});" //重新整理行號,(重要) + XID + ".view.refresh();"; PageContext.RegisterStartupScript(js); } //綁定樹點擊事件 TreeClick(); } }邏輯就是得到刪除的行號,排序,緩衝,js實現,注意重新整理行號方法和XID的意義。加上方法TreeClick方法寫在了ShowTree裡
下面就可以做展開和收合了,再建一個參數記錄展開的行號,專業版執行個體裡可以通過屬性控制指定列的展開,我控制這個參數可以實現(這個方法沒有寫只是理論上的...)
private static List<string> _RowCollapsed;//展開集合 /// <summary> /// 展開集合 /// </summary> public static List<string> RowCollapsed { get { return _RowCollapsed; } set { _RowCollapsed = value; } }
其實這裡可以留扣了,邏輯說出來也不複雜,就都一次寫出來吧
/// <summary> /// 點擊樹事件 /// </summary> /// <param name="treenode">點擊的節點(行號)</param> public void DoTreeClick(string treenode) { if (EnableTree) { StringBuilder sb = new StringBuilder(); List<string> movelist = null; if (movelist == null) { //集合 if (RowCollapsed == null) { RowCollapsed = new List<string>(); } //每次點擊更改集合,移出和新增 if (RowCollapsed.Contains(treenode)) { RowCollapsed.Remove(treenode); } else { RowCollapsed.Add(treenode); } movelist = new List<string>(moveindex.Split(‘,‘)); } int PIDindex = FindColumn(TreeDataParentIDField).ColumnIndex; int IDindex = FindColumn(TreeDataIDField).ColumnIndex; //得到下級菜單 string nextindex = GetNextIndex(Rows[Convert.ToInt32(treenode)], Rows); if (nextindex != "") { string[] s = nextindex.Split(‘,‘); for (int i = 0; i < s.Length; i++) { GridRow dr = Rows[Convert.ToInt32(s[i])]; string rowindex = dr.RowIndex.ToString(); //收合動作迴圈子集收合 if (!RowCollapsed.Contains(treenode)) { movelist.Add(rowindex); DoNextTreeClick(rowindex, ref movelist, false); } //展開迴圈子集展開 else { movelist.Remove(rowindex); if (RowCollapsed.Contains(rowindex)) { DoNextTreeClick(rowindex, ref movelist, true); } } } moveindex = ""; if (movelist.Count >= 2) { movelist.Sort(delegate(string str1, string str2) { return int.Parse(str2 == "" ? "0" : str2) - int.Parse(str1 == "" ? "0" : str1); }); } foreach (string ss in movelist) { moveindex += moveindex == "" ? ss : "," + ss; } if (moveindex != null) { string js = "" //+"F.ready(function(){" + "var store =F(‘" + ClientID + "‘).getStore();" + "var rows = [" + moveindex + "];" + "Ext.Array.each(rows, function (rowIndex, index) {" + " store.removeAt(rowIndex);" + "});" //+ XID + ".f_loadData();" + "F(‘" + ClientID + "‘).view.refresh();"; //+ "});"; //sb.Append(js); sb.Append("F(‘" + ClientID + "‘).f_loadData();"); sb.Append(js); } PageContext.RegisterStartupScript(sb.ToString()); } TreeClick(); } } /// <summary> /// 迴圈子集 /// </summary> /// <param name="treeindex"></param> /// <param name="movelist"></param> private void DoNextTreeClick(string treeindex, ref List<string> movelist, bool Collapsed) { if (EnableTree) { StringBuilder sb = new StringBuilder(); int PIDindex = FindColumn(TreeDataParentIDField).ColumnIndex; int IDindex = FindColumn(TreeDataIDField).ColumnIndex; //得到下一菜單 string nextindex = GetNextIndex(Rows[Convert.ToInt32(treeindex)], Rows); if (nextindex != "") { string[] s = nextindex.Split(‘,‘); for (int i = 0; i < s.Length; i++) { GridRow dr = Rows[Convert.ToInt32(s[i])]; string rowindex = dr.RowIndex.ToString(); //展開 if (movelist.Contains(rowindex) && Collapsed) { movelist.Remove(rowindex); } //收合 if (!Collapsed && !movelist.Contains(rowindex)) { movelist.Add(rowindex); } //展開子集在展開集合中則執行該子集的展開 if (Collapsed && RowCollapsed.Contains(rowindex)) { DoNextTreeClick(rowindex, ref movelist, true); } } } } }
就是點擊展開子集,這裡判斷子集已經展開就繼續展開子集,收合要收合該子集的所有子集,主要是參數邏輯的計算。至此功能全部實現
下面應該寫表徵圖的展開和收合的改變,全部的前台實現,及其他編輯選擇鎖定列的測試和修改
ASP.NET-FineUI開發實踐-13(二)