上篇文章中做了简单实现,但是还是有bug的,还需要在外面写事件的处理,今天又进行修改了。

下面放出代码,同样的  hzh modify标记的就是我进行修改的地方

grid.cs 添加代码

   #region hzh modify
/// <summary>
/// 是否启用树(扩展)
/// </summary>
[Category(CategoryName.OPTIONS)]
[DefaultValue(null)]
[Description("是否启用树(扩展)")]
public bool EnableTree
{
get
{
object obj = FState["EnableTree"];
return obj == null ? false : (bool)obj;
}
set
{
FState["EnableTree"] = value;
if (value)
{
EnableRowClickEvent = false;
}
}
} /// <summary>
/// 是否展开树(扩展)
/// </summary>
[Category(CategoryName.OPTIONS)]
[DefaultValue(null)]
[Description("是否展开树(扩展)")]
public bool ExpandAll
{
get
{
object obj = FState["ExpandAll"];
return obj == null ? true : (bool)obj;
}
set
{
FState["ExpandAll"] = value;
if (value)
{
EnableRowClickEvent = false;
}
}
}
/// <summary>
/// 树节点列名(扩展)
/// </summary>
[Category(CategoryName.OPTIONS)]
[DefaultValue(null)]
[Description("树节点列名(扩展)")]
public string TreeName
{
get
{
object obj = FState["TreeName"];
return obj == null ? "" : (string)obj;
}
set
{
FState["TreeName"] = value;
}
} /// <summary>
/// 主键ID(扩展)
/// </summary>
[Category(CategoryName.OPTIONS)]
[DefaultValue(null)]
[Description("主键ID(扩展)")]
public string TreeDataIDField
{
get
{
object obj = FState["TreeDataIDField"];
return obj == null ? "" : (string)obj;
}
set
{
FState["TreeDataIDField"] = value;
}
}
/// <summary>
/// 父节点列名(扩展)
/// </summary>
[Category(CategoryName.OPTIONS)]
[DefaultValue(null)]
[Description("父节点列名(扩展)")]
public string TreeDataParentIDField
{
get
{
object obj = FState["TreeDataParentIDField"];
return obj == null ? "" : (string)obj;
}
set
{
FState["TreeDataParentIDField"] = value;
}
} /// <summary>
/// 得到当然行的层级(扩展)
/// </summary>
/// <param name="row">当前行</param>
/// <param name="Rows">行数据集</param>
/// <returns>层级</returns>
private int GetLevelNub(GridRow row, GridRowCollection Rows)
{
int lub = ;
//ID所在列
int IDindex = FindColumn(TreeDataIDField).ColumnIndex;
//父ID所在列
int ParentIDindex = FindColumn(TreeDataParentIDField).ColumnIndex;
//如果过是第第一级就是0
if (row.Values[ParentIDindex].ToString() == "" || row.Values[ParentIDindex].ToString() == "")
{
return lub;
}
else
{
foreach (GridRow gr in Rows)
{
//如果有父级
if (gr.Values[IDindex].ToString() == row.Values[ParentIDindex].ToString())
{
//层级加1
lub++;
//查看父级的父级
int nub = GetLevelNub(gr, Rows);
lub += nub == ? : nub;
}
}
}
return lub;
} private List<GridRow> InsertRowToList(List<GridRow> toList, List<GridRow> sourceRows, int idindex, int pridindex)
{
for (int i = toList.Count - ; i >= ; i--)
{
GridRow torow = toList[i];
bool ismodify = false;
if (sourceRows == null || sourceRows.Count <= )
return toList;
for (int j = sourceRows.Count - ; j >= ; j--)
{
GridRow baserow = sourceRows[j];
if (baserow.Values[pridindex].ToString() != "" && baserow.Values[pridindex].ToString() == torow.Values[idindex].ToString())
{
toList.Insert(i + , baserow);
sourceRows.RemoveAt(j);
ismodify = true;
}
}
if (sourceRows.Count <= )
{
sourceRows.Clear();
sourceRows = null;
return toList;
}
if (ismodify == false)
{
if (sourceRows.Count > )
{
foreach (GridRow item in sourceRows)
{
toList.Add(item);
}
sourceRows.Clear();
sourceRows = null;
}
return toList;
}
}
return InsertRowToList(toList, sourceRows, idindex, pridindex);
} /// <summary>
/// 对rows进行重新排序(扩展)
/// </summary>
private void SortTreeRows()
{
List<GridRow> sourceRows = new List<GridRow>();
foreach (GridRow row in Rows)
{
sourceRows.Add(row);
}
Rows.Clear(); List<GridRow> toList = new List<GridRow>(); int pidindex = FindColumn(TreeDataParentIDField).ColumnIndex;
int idindex = FindColumn(TreeDataIDField).ColumnIndex;
for (int i = sourceRows.Count - ; i >= ; i--)
{
GridRow row = sourceRows[i];
if (row.Values[pidindex].ToString() == "" || row.Values[pidindex].ToString() == "")
{
toList.Insert(, row);
sourceRows.RemoveAt(i);
}
} toList = InsertRowToList(toList, sourceRows, idindex, pidindex);
toList.ForEach(p => Rows.Add(p));
for (int i = ; i < Rows.Count; i++)
{
Rows[i].RowIndex = i;
}
toList.Clear();
toList = null;
} /// <summary>
/// 给树赋值(扩展)
/// </summary>
private void SetValueTree()
{
if (EnableTree)
{
foreach (GridRow row in Rows)
{
//下级行数
string Nextindex = GetNextIndex(row, Rows);
//默认图标
Icon iconindex = FineUI.Icon.ControlBlankBlue;
// string iconname = "page.png";
//图片ID,点击用,绑定事件
string imgid = ClientID + "_tree_icon_" + row.RowIndex;
//父节点图标
if (Nextindex != "")
{
if (ExpandAll)
{
iconindex = FineUI.Icon.ControlRemoveBlue;
//设置展开行
RowCollapsed.Add(row.RowIndex.ToString());
}
else
{
iconindex = FineUI.Icon.ControlAddBlue;
}
// iconname = "folder.png"; //加入图标和ID,注意加过的就不加了
if (row.Values[FindColumn(TreeName).ColumnIndex].ToString().IndexOf(ClientID + "_tree_icon_") < )
{
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[];
}
}
}
}
} /// <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;
} /// <summary>
/// 得到所有子类行号
/// </summary>
/// <param name="row">本节点</param>
/// <param name="Rows">集合</param>
/// <param name="strIndexs">集合以,隔开</param>
/// <returns>集合以,隔开</returns>
private void GetAllNextIndex(int rowindex, GridRowCollection Rows, ref string strIndexs)
{
string index = GetNextIndex(Rows[rowindex], Rows);
if (string.IsNullOrEmpty(index.Trim()))
return;
strIndexs = string.IsNullOrEmpty(strIndexs) ? index : (strIndexs + "," + index);
string[] indexs = index.Split(',');
foreach (string item in indexs)
{
GetAllNextIndex(int.Parse(item), Rows, ref strIndexs);
}
} /// <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());
} // private static string _moveindex;//移除的数据
/// <summary>
/// 移除的数据(扩展)
/// </summary>
public List<string> MoveIndex
{
get
{
object obj = ViewState["MoveIndex"];
return obj == null ? new List<string>() : obj as List<string>;
}
set
{ ViewState["MoveIndex"] = value;
}
} // private static List<string> _RowCollapsed;//展开集合
/// <summary>
/// 展开集合(扩展)
/// </summary>
public List<string> RowCollapsed
{
get
{
object obj = ViewState["RowCollapsed"];
return obj == null ? new List<string>() : obj as List<string>;
}
set
{ ViewState["RowCollapsed"] = value;
}
} /// <summary>
/// 第一次显示数方法(扩展)
/// </summary>
private void ShowTree()
{
//初始化树
if (EnableTree)
{
if (!ExpandAll)
{
List<string> lstMove = new List<string>();
//循环行
foreach (GridRow row in Rows)
{
//得到层级
int lub = GetLevelNub(row, Rows);
if (lub != )
{
//子集删除
if (!lstMove.Contains(row.RowIndex.ToString()))
lstMove.Add(row.RowIndex.ToString());
}
}
//排序(重要) 从大到小排序,不排序会删除1后造成2变成1
lstMove.Sort(delegate(string str1, string str2) { return int.Parse(str2) - int.Parse(str1); });
if (MoveIndex == null || MoveIndex.Count == )
MoveIndex = lstMove;
string strMoveIndex = string.Empty;
foreach (string item in lstMove)
{
strMoveIndex += string.IsNullOrEmpty(strMoveIndex) ? item : ("," + item);
} string js = string.Empty;
if (!string.IsNullOrEmpty(strMoveIndex))
{
//放入缓存记录已经消除的行 js = ""
+ "var store =" + XID + ".getStore();"
+ "var rows = [" + strMoveIndex + "];"
+ "Ext.Array.each(rows, function (rowIndex, index) {"
+ " store.removeAt(rowIndex);"
+ "});"
//刷新行号,(重要)
+ XID + ".view.refresh();"; }
if (!string.IsNullOrEmpty(js))
PageContext.RegisterStartupScript(js);
//绑定树点击事件
TreeClick();
}
else
{
List<string> _RowCollapsed = new List<string>();
//循环行
foreach (GridRow row in Rows)
{
//得到层级
if (!string.IsNullOrEmpty(GetNextIndex(row, Rows)))
{
if (!_RowCollapsed.Contains(row.RowIndex.ToString()))
_RowCollapsed.Add(row.RowIndex.ToString());
}
}
RowCollapsed = _RowCollapsed;
//绑定树点击事件
TreeClick();
}
}
} /// <summary>
/// 点击树事件(扩展)
/// </summary>
/// <param name="treenode">点击的节点(行号)</param>
public void DoTreeClick(string treenode)
{
if (EnableTree)
{ string strIconJs = string.Empty;
StringBuilder sb = new StringBuilder();
string[] strsmove = new string[MoveIndex.Count];
MoveIndex.CopyTo(strsmove);
List<string> _MoveIndex = new List<string>(strsmove);
string[] strscoll = new string[RowCollapsed.Count];
RowCollapsed.CopyTo(strscoll);
List<string> _RowCollapsed = new List<string>(strscoll);
// ShowTree();
//集合
if (_RowCollapsed == null)
{
_RowCollapsed = new List<string>();
}
//每次点击更改集合,移出和新增
if (_RowCollapsed.Contains(treenode))
{
_RowCollapsed.Remove(treenode);
string strids = string.Empty;
GetAllNextIndex(int.Parse(treenode), Rows, ref strids);
if (!string.IsNullOrEmpty(strids.Trim()))
{
string[] ids = strids.Split(',');
foreach (string item in ids)
{
_RowCollapsed.Remove(item);
string imgid = ClientID + "_tree_icon_" + item;
strIconJs += "$(\"#" + imgid + "\").attr(\"src\",\"" + IconHelper.GetResolvedIconUrl(FineUI.Icon.ControlAddBlue) + "\");";
if (!_MoveIndex.Contains(item))
_MoveIndex.Add(item);
}
}
}
else
{
if (!_RowCollapsed.Contains(treenode))
_RowCollapsed.Add(treenode);
string strids = GetNextIndex(Rows[int.Parse(treenode)], Rows);
if (!string.IsNullOrEmpty(strids.Trim()))
{
string[] ids = strids.Split(',');
foreach (string item in ids)
{
_MoveIndex.Remove(item);
}
}
} int PIDindex = FindColumn(TreeDataParentIDField).ColumnIndex;
int IDindex = FindColumn(TreeDataIDField).ColumnIndex; if (_MoveIndex.Count >= )
{
_MoveIndex.Sort(delegate(string str1, string str2) { return int.Parse(str2 == "" ? "" : str2) - int.Parse(str1 == "" ? "" : str1); });
}
string strMoveIndex = string.Empty;
foreach (string ss in _MoveIndex)
{
strMoveIndex += strMoveIndex == "" ? ss : "," + ss;
} RowCollapsed = _RowCollapsed;
MoveIndex = _MoveIndex; if (strMoveIndex != null)
{
string js = ""
//+"F.ready(function(){"
+ "var store =F('" + ClientID + "').getStore();"
+ "var rows = [" + strMoveIndex + "];"
+ "Ext.Array.each(rows, function (rowIndex, index) {"
+ " store.removeAt(rowIndex);"
+ "});"
//+ XID + ".f_loadData();"
+ "F('" + ClientID + "').view.refresh();"; sb.Append("F('" + ClientID + "').f_loadData();");
sb.Append(js); }
sb.Append(strIconJs);
foreach (string item in RowCollapsed)
{
string imgid = ClientID + "_tree_icon_" + item;
sb.Append("$(\"#" + imgid + "\").attr(\"src\",\"" + IconHelper.GetResolvedIconUrl(FineUI.Icon.ControlRemoveBlue) + "\");");
} 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 = ; 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);
}
}
}
}
} /// <summary>
/// 处理自定义事件(扩展)
/// </summary>
/// <param name="e"></param>
public void CheckCustomEventArgs(CustomEventArgs e)
{
if (EnableTree && !string.IsNullOrEmpty(TreeName) && !string.IsNullOrEmpty(TreeDataIDField) && !string.IsNullOrEmpty(TreeDataParentIDField))
{
if (e.EventArgument.IndexOf("GridTreeClick_") >= )
{
string rowindex = e.EventArgument.ToString().Split('_')[];
DoTreeClick(rowindex);
}
}
} #endregion

grid.cs 修改代码

   private void AfterDataBind(int recordCount)
{
#region hzh modify
if (EnableTree && !string.IsNullOrEmpty(TreeName) && !string.IsNullOrEmpty(TreeDataIDField) && !string.IsNullOrEmpty(TreeDataParentIDField))
{
SortTreeRows();
SetValueTree();
ShowTree(); }
#endregion
if (!IsDatabasePaging)
{
// 如果不是数据库分页,则每次DataBind都要更新RecordCount的值
// 数据库分页的话,RecordCount需要用户显式的赋值
RecordCount = recordCount;
} // 在所有行都绑定结束后,需要检查模拟树显示的列,并重新计算当前列的内容(在列内容前加上树分隔符)
// 1.查找需要模拟树显示的列
BaseField simulateTreeColumn = null;
foreach (GridColumn gridColumn in AllColumns)
{
BaseField column = gridColumn as BaseField;
if (column != null && !String.IsNullOrEmpty(column.DataSimulateTreeLevelField))
{
simulateTreeColumn = column;
break;
}
}
#region hzh modify
if (EnableTree)
{
if (!string.IsNullOrEmpty(TreeName))
{
simulateTreeColumn = FindColumn(TreeName) as BaseField;
}
}
#endregion // 2.如果找到这样的列
if (simulateTreeColumn != null)
{
List<SimulateTreeNode> silumateTree = new List<SimulateTreeNode>(); // 存在需要模拟树显示的列
for (int rowIndex = , rowCount = Rows.Count; rowIndex < rowCount; rowIndex++)
{
GridRow row = Rows[rowIndex];
int level = ;
#region hzh modify
if (EnableTree)
{
level = GetLevelNub(row, Rows) - ;
}
else
{
object treeLevelObj = row.GetPropertyValue(simulateTreeColumn.DataSimulateTreeLevelField);
if (treeLevelObj != null && treeLevelObj != DBNull.Value)
{
level = Convert.ToInt32(treeLevelObj);
}
}
#endregion
object content = row.Values[simulateTreeColumn.ColumnIndex]; SimulateTreeNode node = new SimulateTreeNode();
node.Text = content.ToString();
node.Level = level;
node.HasLittleBrother = false;
node.ParentNode = null;
silumateTree.Add(node);
} // 计算树
SimulateTreeHeper treeHelper = new SimulateTreeHeper();
treeHelper.ResolveSimulateTree(silumateTree, true); // 赋值
for (int rowIndex = , rowCount = Rows.Count; rowIndex < rowCount; rowIndex++)
{
Rows[rowIndex].Values[simulateTreeColumn.ColumnIndex] = silumateTree[rowIndex].Text;
}
} }

pagemanager.cs添加代码

   #region hzh modify
/// <summary>
/// 设置treegrid自定义事件
/// </summary>
/// <param name="e"></param>
private void SetCustomEventArgs(CustomEventArgs e)
{
if (!string.IsNullOrEmpty(TreeGridID))
{
Grid grid = ControlUtil.FindControl(TreeGridID) as Grid;
grid.CheckCustomEventArgs(e);
}
}
/// <summary>
/// TreeGridID(扩展)
/// </summary>
[Category(CategoryName.OPTIONS)]
[DefaultValue(null)]
[Description("TreeGridID(扩展)")]
public string TreeGridID
{
get
{
object obj = FState["TreeGridID"];
return obj == null ? "" : obj.ToString();
}
set
{
FState["TreeGridID"] = value;
}
}
#endregion

pagemanager.cs修改代码

    /// <summary>
/// 触发自定义事件
/// </summary>
/// <param name="e">事件参数</param>
protected virtual void OnCustomEvent(CustomEventArgs e)
{
#region hzh modify
SetCustomEventArgs(e);
#endregion
EventHandler<CustomEventArgs> handler = Events[_handlerKey] as EventHandler<CustomEventArgs>;
if (handler != null)
{
handler(this, e);
}
}

测试页面代码

 <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="TestPage.aspx.cs" Inherits="FineUI.Examples.TestPage" %>

 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<f:PageManager ID="PageManager1" runat="server" TreeGridID="Grid1"/>
<f:Grid EnableCollapse="true" Width="800px" Height="400px" runat="server" DataKeyNames="Id,Name"
ID="Grid1" EnableTree="true" TreeName="name" TreeDataIDField="id" TreeDataParentIDField="topID"
ShowBorder="true" ShowHeader="true" Title="树表格" ExpandAll="false">
<Columns>
<f:RowNumberField />
<f:BoundField ColumnID="name" ExpandUnusedSpace="true" DataField="name" HeaderText="名称">
</f:BoundField>
<f:BoundField ColumnID="id" DataField="id" Width="50px" HeaderText="ID">
</f:BoundField>
<f:BoundField ColumnID="topID" DataField="topID" Width="50px" HeaderText="topID">
</f:BoundField>
<f:BoundField DataField="levelcode" Width="100px" HeaderText="层级编号">
</f:BoundField>
<f:BoundField ColumnID="levelnub" DataField="levelnub" Width="100px" HeaderText="层级数">
</f:BoundField>
<f:BoundField DataField="subitem" Width="100px" HeaderText="是否为子菜单">
</f:BoundField>
<f:BoundField DataField="url" Width="100px" HeaderText="地址">
</f:BoundField>
</Columns>
</f:Grid>
</form>
<script src="./res/js/jquery.min.js"></script>
</body>
</html>
 using System;
using System.Collections.Generic; using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data; namespace FineUI.Examples
{
public partial class TestPage : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (IsPostBack)
return;
DataTable dt = new DataTable();
dt.Columns.Add("name", typeof(string));
dt.Columns.Add("id", typeof(int));
dt.Columns.Add("topID", typeof(string));
dt.Columns.Add("levelcode", typeof(string));
dt.Columns.Add("levelnub", typeof(int));
dt.Columns.Add("subitem", typeof(bool));
dt.Columns.Add("url", typeof(string)); DataRow dr1 = dt.NewRow();
dr1[] = "首页";
dr1[] = ;
dr1[] = ;
dr1[] = "";
dr1[] =;
dr1[] = false;
dr1[] = "adfsdfds";
dt.Rows.Add(dr1); DataRow dr2 = dt.NewRow();
dr2[] = "测试页";
dr2[] = ;
dr2[] = ;
dr2[] = "";
dr2[] = ;
dr2[] = false;
dr2[] = "adfsdfds";
dt.Rows.Add(dr2); //==================== DataRow dr11 = dt.NewRow();
dr11[] = "首页下级1";
dr11[] = ;
dr11[] = ;
dr11[] = "";
dr11[] = ;
dr11[] = true;
dr11[] = "adfsdfds";
dt.Rows.Add(dr11); DataRow dr12 = dt.NewRow();
dr12[] = "首页下级2";
dr12[] = ;
dr12[] = ;
dr12[] = "";
dr12[] = ;
dr12[] = true;
dr12[] = "adfsdfds";
dt.Rows.Add(dr12); DataRow dr13 = dt.NewRow();
dr13[] = "首页下级3";
dr13[] = ;
dr13[] = ;
dt.Rows.Add(dr13); //======================== DataRow dr21 = dt.NewRow();
dr21[] = "测试页下级1";
dr21[] = ;
dr21[] = ;
dr21[] = "";
dr21[] = ;
dr21[] = true;
dr21[] = "adfsdfds";
dt.Rows.Add(dr21); DataRow dr22 = dt.NewRow();
dr22[] = "测试页下级2";
dr22[] = ;
dr22[] = ;
dr22[] = "";
dr22[] = ;
dr22[] = true;
dr22[] = "adfsdfds";
dt.Rows.Add(dr22); DataRow dr221 = dt.NewRow();
dr221[] = "测试页下下级1";
dr221[] = ;
dr221[] = ;
dr221[] = "";
dr221[] = ;
dr221[] = true;
dr221[] = "adfsdfds";
dt.Rows.Add(dr221); DataRow dr00 = dt.NewRow();
dr00[] = "00测试";
dr00[] = ;
dr00[] = ;
dr00[] = "";
dr00[] = ;
dr00[] = true;
dr00[] = "adfsdfds";
dt.Rows.Add(dr00); Grid1.DataSource = dt;
Grid1.DataBind();
} }
}

效果图:

FineUI开源版之TreeGrid(修改)的更多相关文章

  1. FineUI开源版之TreeGrid实现

    FineUI开源版是没有树表格的,但是又需要,怎么办呢?在博客园看到一位大大的文章 http://www.cnblogs.com/shiworkyue/p/4211002.html 然后参考,不知道为 ...

  2. FineUI开源版(ASP.Net)初学手册

    女朋友鄙视我原创少... 1.下载 进入官方论坛:http://www.fineui.com/bbs/ 要用到下载源代码和空项目下载 http://fineui.codeplex.com/ http: ...

  3. FineUI开源版(ASP.Net)开发实践-目录

    点我订阅 目前所有博客的截图,方便离线观看,点图片 FineUI初学手册 下载,实例项目搭建 FineUI初学手册-部分JS整理 部分JS整理 ASP.NET-FineUI开发实践-1 实际开发环境是 ...

  4. FineUI开源版(ASP.Net)初学手册-部分JS整理

    有人老找JS,我吧FineUI自己写的JS沾过来方便大家看看,在实现前端的时候更灵活   JS 实例 注释 控件 F.ready F.ready(function(){}); 就是ready 很多方法 ...

  5. FineUI(开源版)v6.0中FState服务器端验证的实现原理

    前言 1. FineUI(开源版)是完整开源,最早发起于 2008-04,下载全部源代码:http://fineui.codeplex.com/ 2. 你可以通过捐赠作者来支持FineUI(开源版)的 ...

  6. FineUI(开源版)v4.2.2发布(8年125个版本,官网示例突破300个)!

    开源版是 FineUI 的基石,从 2008 年至今已经持续发布了 120 多个版本,拥有会员 15,000 多位,捐赠会员达到 1,200 多位.   FineUI(开源版)v4.2.2 是 8 年 ...

  7. FineUI(专业版)v1.2.0 和 FineUI(开源版)v4.1.1 同时发布!

    FineUI(开源版)v4.1.1 (建议所有 v4.x 升级到此版本):http://fineui.com/demo/ +2014-08-15 v4.1.1        -修正Form中表单字段设 ...

  8. 【开源】接口管理平台eoLinker AMS 开源版3.1.5同步线上版!免费增加大量功能!

    概要:eoLinker是一个免费开源的针对开发人员需求而设计的接口管理工具,通过简单的操作来帮助开发者进行接口文档管理.接口自动化测试.团队协作.数据获取.安全防御监控等功能,降低企业的接口管理成本, ...

  9. 部署eolinker开源版接口管理

    想找一个API接口管理的软件,为了安全性和扩展性考虑,希望是开源的,而且可以在内网独立部署.网上翻找了资料,经过一份比对之后,最终采用eolinker.过去有使用过RAP,但是感觉界面实在是太丑了. ...

随机推荐

  1. HDU 4946 Area of Mushroom 凸包 第八次多校

    题目链接:hdu 4946 题意:一大神有N个学生,各个都是小神,大神有个二次元空间,每一个小神都有一个初始坐标,如今大神把这些空间分给徒弟们,规则是假设这个地方有一个人比谁都先到这,那么这个地方就是 ...

  2. 它们的定义ListView,实现Item除去滑动和滑出菜单效果

    这个程序是基于变化从网上开源项目,详情货源忘记.懒得去搜索,.假设有不合适的地方.请与我联系作者.我会及时回复和处理! 序中主要包括两个ListView,一个是实现側滑删除.一个是側滑出菜单,代码中的 ...

  3. Hibernate各保存方法之间的差 (save,persist,update,saveOrUpdte,merge,flush,lock)等一下

    hibernate保存  hibernate要保存的目的是提供一个方法,多.它们之间有许多不同之处,点击此处详细说明.使得差: 一.预赛: 在所有.阐释.供hibernate,,transient.p ...

  4. ABP入门教程

    ABP入门教程 ABP是“ASP.NET Boilerplate Project (ASP.NET样板项目)”的简称. ASP.NET Boilerplate是一个用最佳实践和流行技术开发现代WEB应 ...

  5. Effective C++之‘宁以pass-by-reference-to-const替换pass-by-value’

    Effective C++之'宁以pass-by-reference-to-const替换pass-by-value' 缺省情况下C++以by value 方式(一个继承自C的方式)传递对象至函数.除 ...

  6. Java 测试并行编程(三)

    有很多其他的交替运行 因为在并行代码中的错误一般是低概率事件.因此,试运行并发差错时需要反复多次,但是,有很多方法可以提高发现这些错误的概率 ,在前面提到的,在多处理器系统.假设 线程的数量,那么 与 ...

  7. Cracking Microservices practices

    微服务最佳实践 英文原文:Cracking Microservices practices 在我还不知道什么叫微服务架构的时候我就使用过它.以前,我写了一些管道程序(pipeline applicat ...

  8. 省钱加油(Fuel Economy)题解

    题目 农夫约翰决定去做一个环游国家旅行,为了不让他的奶牛们感到孤单,于是他决定租一辆货车带领他的奶牛们一起去旅行.这辆货车的油箱最多可以承载G 个单位的油,同时为了简化问题,规定每一个单位的油可以行使 ...

  9. EasyMonkeyDevice vs MonkeyDevice&HierarchyViewer API Mapping Matrix

    1. 前言 本来这次文章的title是写成和前几篇类似的<EasyMonkeyDevice API实践全记录>,内容也打算把每个API的实践和建议给记录下来,但后来想了下觉得这样子并不是最 ...

  10. SQL点滴33—SQL中的字符串操作

    原文:SQL点滴33-SQL中的字符串操作 计算字符串长度len()用来计算字符串的长度 select sname ,len(sname) from student 字符串转换为大.小写lower() ...