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(二)的更多相关文章

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

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

  2. FineUI开发实践-目录

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

  3. FineUI开发实践

    ASP.NET-FineUI开发实践-7 摘要: 下拉显示grid列表.其实很简单,但是试了很多方法,水平有限,主要是都不好使,还是简单的好使了,分享下.先是看了看网上的,是直接写个了extjs控件类 ...

  4. Xamarin.Android开发实践(二)

    原文:Xamarin.Android开发实践(二) 一.准备 开始学习本教程前必须先完成该教程http://www.cnblogs.com/yaozhenfa/p/xamarin_android_qu ...

  5. 使用ADO实现BLOB数据的存取 -- ADO开发实践之二

    使用ADO实现BLOB数据的存取 -- ADO开发实践之二 http://www.360doc.com/content/11/0113/16/4780948_86256633.shtml 一.前言 在 ...

  6. ASP.NET-FineUI开发实践-16(二)

    实现那还差点,在事件参数里我传了一个boolall选中状态参数,这个参数由前台给的,RowSelect 传的是index 行号,就是改这,通过$符号来分开的, if (commandArgs.Leng ...

  7. ASP.NET-FineUI开发实践-13(一)

    开原版好像是没有gird树,有一个扩展列下的模拟树列,就是不能展开,专业版有,开原版我弄了弄,思路是有,就是不是很好实现.这篇博客直接写出了(一)说明一个肯定是写不完的. FineUI重在封装,改这个 ...

  8. ASP.NET-FineUI开发实践-9(二)

    其实我也不会,老实教人学怕误人子弟,但是抱着毁人不倦的精神还是糊弄糊弄个别小白吧,最起码能加点原创. 下面以表单为例,打开官方项目,版本为FineUI_4.1.1,打开form_compare页,右键 ...

  9. ASP.NET-FineUI开发实践-4(二)

    在网上找了找,实验了一下window弹出和关闭的动画效果分享一下. 接上次的代码 default.js window_tips.animCollapse= true;//打开动画效果 window_t ...

随机推荐

  1. nginx+uwsgi+WSGI applications

    uwsgi一个专业的部署运用的工具,不仅能够部署Python运用,还能够部署其他运用比如Perl,Ruby等 uWSGI 安装: pip install uwsgi WSGI application( ...

  2. BZOJ 1207 打鼹鼠

    Description 鼹鼠是一种很喜欢挖洞的动物,但每过一定的时间,它还是喜欢把头探出到地面上来透透气的.根据这个特点阿Q编写了一个打鼹鼠的游戏:在一个n*n的网格中,在某些时刻鼹鼠会在某一个网格探 ...

  3. BZOJ 1017 魔兽地图

    Description DotR (Defense of the Robots) Allstars是一个风靡全球的魔兽地图,他的规则简单与同样流行的地图DotA (Defense of the Anc ...

  4. [转]Getting (personal) tasks from the user profile.

    from http://blog.amtopm.be/2013/02/22/getting-personal-tasks-from-the-user-profile/ Getting (persona ...

  5. Unity3D 3D横版跑酷 跳跃

    Unity3d 跑酷动画的控制 首先给个图吧, 我们跑酷里面需要动画的,今天说一下动画的知识! 1.导入骨骼动画模型文件之后,如果使用之前版本的unity的播放动画的方式,需要设置AnimationT ...

  6. ios开发学习- 简易音乐播放器2 (基于iPhone4s屏幕尺寸)-- 歌词解析--plist文件应用--imageNamed图片加载耗内存

    声明:(部分图片来自网络,如果侵犯了您的权益请联系我,会尽快删除!) 又是音乐播放器,不过这次和上次不一样了,准确说这次更像播放器了,初学者不建议看这个,可以先看前面一个音乐播放器(1),当然 我没加 ...

  7. 如何给Qlabel添加clicked属性(覆盖mousePressEvent,处理QMouseEvent消息,反正是软绘制,想怎么样就怎么样)

    clickedLabel.h #ifndef CLICKLABEL_H #define CLICKLABEL_H #include <QLabel> #include <QMouse ...

  8. Hibernate 配置详解(3)

    7) hibernate.max_fetch_depth: 该属性用于设置left out join单对象查询关系(one-to-one/many-to-one)中最大的关联深度.默认值为0,即默认情 ...

  9. -_-#【Better JS Code】严格模式

    要在整个脚本中启用严格模式,可以在顶部添加如下代码: "use strict"; 这行代码看起来像是字符串,而且也没有赋值给任何变量,但其实它是一个编译指示,用于告诉支持的 Jav ...

  10. 数据结构(线段树):CodeForces 145E Lucky Queries

    E. Lucky Queries time limit per test 3 seconds memory limit per test 256 megabytes input standard in ...