支持树型的GridView控件
支持树型的GridView
实现思路: 继承自Gridview,处理gridview的数据源,使其在帮定时,就已经按照树型菜单顺序排列好,那样只需在帮定处理其图片是javascript脚本就可以了
。
源代码下载:http://files.cnblogs.com/wschacker/TreeListView.rar
效果图:
代码:
using System;
using System.Data;
using System.Collections;
using System.Collections.Specialized;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text;
using System.Web;
using System.IO;
using System.Drawing;
using System.Drawing.Design;
using System.Reflection;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
[ToolboxData("<{0}:TreeListView runat=server></{0}:TreeListView>"), DefaultProperty("Text")]
public class TreeListView : GridView, IPostBackDataHandler
{
public TreeListView()
{
base.AllowPaging = false;
base.AllowSorting = false;
base.AutoGenerateColumns = false;
}
Tree的属性设置#region Tree的属性设置
private int _nodeColumnIndex;
/**//// <summary>
/// 显示树型的列 Index
/// </summary>
public int NodeColumnIndex
{
get { return this._nodeColumnIndex; }
set
{
_nodeColumnIndex = value;
}
}
private string _columnKey;
/**//// <summary>
/// Key字段
/// </summary>
public string ColumnKey
{
get { return _columnKey; }
set
{
_columnKey = value;
}
}
private string _parentKey;
/**//// <summary>
/// 指向父节点的字段
/// </summary>
public string ParentKey
{
set
{
_parentKey = value;
}
}
private string _sortKey;
/**//// <summary>
/// 排序字段
/// </summary>
public string SortKey
{
set { _sortKey = value; }
}
private object _rootNodeFlag;
/**//// <summary>
/// 根节点的标记 这里采用 ParentKey为什么字符
/// </summary>
public object RootNodeFlag
{
set
{
_rootNodeFlag = value;
}
}
private static string _treeImageFolder = "/Images/Tree/";
public static string TreeImageFolder
{
get
{
return _treeImageFolder;
}
set
{
_treeImageFolder = value;
}
}
private int _expendDepth = 0;
/**//// <summary>
/// 展开的深度
/// </summary>
public int ExpendDepth
{
get
{
return _expendDepth;
}
set { _expendDepth = value; }
}
#endregion
public override object DataSource
{
get
{
return base.DataSource;
}
set
{
DataTable dtSource = new DataTable();
if (value is DataSet && ((DataSet)value).Tables.Count > 0)
{
DataSet ds = value as DataSet;
dtSource = OrderData(ds.Tables[0]);
}
else
{
throw new Exception("DataSource is not DataSet!");
}
base.DataSource = dtSource;
}
}
DataTable OrderData(DataTable dtSource)
{
DataTable dtResult = dtSource.Clone();
dtResult.Columns.Add("TreeListView$Row$Depth", typeof(int));
dtResult.Columns.Add("TreeListView$Row$IsLeaf", typeof(bool));
dtResult.Columns.Add("TreeListView$Row$IsBottom", typeof(bool));
dtResult.Columns.Add("TreeListView$Row$ParentRow", typeof(DataRow));
dtResult.Columns.Add("TreeList$ViewRow$ClientID", typeof(string));
RecursionOrderData(dtSource, dtResult, _rootNodeFlag, -1, null);
return dtResult;
}
string FormatToRowFilter(object val)
{
Type type = val.GetType();
if (type == typeof(string))
{
return string.Format("'{0}'", val.ToString().Replace("'", "''"));
}
else if (type == typeof(Guid))
{
return string.Format("'{0}'", val);
}
else if (type.IsValueType)
{
return val.ToString();
}
else
{
return string.Format("'{0}'", val.ToString().Replace("'", "''"));
}
}
bool RecursionOrderData(DataTable dtSource, DataTable dtResult, object parentID, int depth, DataRow parentDatarow)
{
DataView dv = new DataView(dtSource);
dv.RowFilter = string.Format("{0}={1}", _parentKey, FormatToRowFilter(parentID));
dv.Sort = _sortKey;
DataRow dr = null;
depth++;
for (int i = 0; i < dv.Count; i++)
{
dr = dtResult.NewRow();
for (int j = 0; j < dv[i].Row.ItemArray.Length; j++)
{
dr[j] = dv[i][j];
}
if (i == dv.Count - 1) //isBottom
{
dr["TreeListView$Row$IsBottom"] = true;
}
else
{
dr["TreeListView$Row$IsBottom"] = false;
}
dr["TreeListView$Row$Depth"] = depth;
dr["TreeListView$Row$ParentRow"] = parentDatarow;
if (depth == 0)
{
dr["TreeList$ViewRow$ClientID"] = Guid.NewGuid().ToString();
}
else
{
dr["TreeList$ViewRow$ClientID"] = parentDatarow["TreeList$ViewRow$ClientID"].ToString() + "/" + Guid.NewGuid().ToString();
}
dtResult.Rows.Add(dr);
dr["TreeListView$Row$IsLeaf"] = !RecursionOrderData(dtSource, dtResult, dv[i][_columnKey], depth, dr);
}
return dv.Count > 0;
}
public override bool AllowPaging
{
get
{
return base.AllowPaging;
}
set
{
base.AllowPaging = false;
}
}
public override bool AutoGenerateColumns
{
get
{
return base.AutoGenerateColumns;
}
set
{
base.AutoGenerateColumns = false;
}
}
重载:CreateRow#region 重载:CreateRow
protected override GridViewRow CreateRow(int rowIndex, int dataSourceIndex, DataControlRowType rowType, DataControlRowState rowState)
{
return new TreeListViewRow(rowIndex, dataSourceIndex, rowType, rowState);
}
#endregion
重写:Rows#region 重写:Rows
private TreeListViewRowCollection _rowsCollection;
[Browsable(false)]
public new TreeListViewRowCollection Rows
{
get
{
ArrayList _rowsArray = new ArrayList();
for (int i = 0; i < base.Rows.Count; i++)
{
_rowsArray.Add((TreeListViewRow)base.Rows[i]);
}
this._rowsCollection = new TreeListViewRowCollection(_rowsArray);
return this._rowsCollection;
}
}
#endregion
重载:OnInit#region 重载:OnInit
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
Page.RegisterRequiresPostBack(this);
if (!Page.ClientScript.IsClientScriptIncludeRegistered("JS_TreeListView"))
{
this.Page.ClientScript.RegisterClientScriptInclude(this.GetType(), "JS_TreeListView", Page.ClientScript.GetWebResourceUrl(this.GetType(), "GoldMantis.Web.UI.Resource.TreeListView.JS_TreeListView.js"));
}
}
#endregion
IPostBackDataHandler Members#region IPostBackDataHandler Members
public bool LoadPostData(string postDataKey, NameValueCollection postCollection)
{
return false;
}
public void RaisePostDataChangedEvent()
{
}
#endregion
方法:RenderCheckBoxExField#region 方法:RenderCheckBoxExField
/**//// <summary>
/// 处理CheckBoxExField类型的列
/// </summary>
private void RenderCheckBoxExField()
{
if (!this.ShowHeader && !this.ShowFooter)
{
return;
}
foreach (DataControlField field in Columns)
{
if (field is CheckBoxExField)
{
int checkBoxExFieldIndex = Columns.IndexOf(field) + this.GetAutoGenerateButtonCount();
foreach (GridViewRow row in Rows)
{
if (row.RowType == DataControlRowType.Header)
{
row.Cells[checkBoxExFieldIndex].Controls.Clear();
}
if (row.RowType == DataControlRowType.DataRow)
{
row.Cells[checkBoxExFieldIndex].Controls[0].ID = "cbChoose";
((CheckBox)row.Cells[checkBoxExFieldIndex].Controls[0]).Attributes.Add("onclick", "ChooseTree(this);");
}
}
注册脚本#region 注册脚本
string script = @"
var modifyId = """" ;
var choosedId = """";
var choosedIndex;
function ChooseTree(obj)
{
var cTrId = obj.parentElement.parentElement.parentElement.id;
var treeTable = document.getElementById("""+this.ClientID+@""");
for( var i = 0; i < treeTable.rows.length; i++ )
{
if( treeTable.rows[i].id.indexOf(cTrId) != -1 && treeTable.rows[i].id != cTrId )
{
document.getElementById(treeTable.rows[i].id+""_cbChoose"").checked = obj.checked;
}
}
choosedId = """";
choosedIndex = new Array();
for( var i = 1; i < treeTable.rows.length; i++ )
{
if( document.getElementById(treeTable.rows[i].id+""_cbChoose"").checked )
{
choosedId += treeTable.rows[i].id.substring(treeTable.rows[i].id.lastIndexOf(""/"")+1) + "","";
choosedIndex.push(i);
}
}
choosedId = choosedId.substring(0,choosedId.length-1);
}";
if (!Page.ClientScript.IsStartupScriptRegistered("TreeListView_CheckBoxExField"))
{
Page.ClientScript.RegisterStartupScript(GetType(), "TreeListView_CheckBoxExField", script, true);
}
#endregion
}
}
}
方法:GetAutoGenerateButtonCount#region 方法:GetAutoGenerateButtonCount
private int GetAutoGenerateButtonCount()
{
int num = 0;
if (this.AutoGenerateDeleteButton || this.AutoGenerateEditButton || this.AutoGenerateSelectButton)
{
num = 1;
}
return num;
}
#endregion
#endregion
protected override void Render(HtmlTextWriter writer)
{
RenderCheckBoxExField();
base.Render(writer);
}
}
{
public TreeListViewRow(int rowIndex, int dataItemIndex, DataControlRowType rowType, DataControlRowState rowState)
: base(rowIndex, dataItemIndex, rowType, rowState)
{
}
protected override void OnPreRender(EventArgs e)
{
base.OnPreRender(e);
if (this.RowType == DataControlRowType.DataRow)
{
if (this.Parent.Parent is TreeListView)
{
TreeListView treeListView = this.Parent.Parent as TreeListView;
DataRow dr = ((DataTable)treeListView.DataSource).Rows[this.DataItemIndex] as DataRow;
string str = GetTreeNodeImg(dr, Convert.ToBoolean(dr["TreeListView$Row$IsLeaf"]), Convert.ToBoolean(dr["TreeListView$Row$IsBottom"]));
this.Cells[treeListView.NodeColumnIndex].Text = str + this.Cells[treeListView.NodeColumnIndex].Text;
this.ID = dr["TreeList$ViewRow$ClientID"].ToString();
if (treeListView.ExpendDepth > 0)
{
this.Style["display"] = treeListView.ExpendDepth >= Convert.ToInt32(dr["TreeListView$Row$Depth"]) ? "block" : "none";
}
}
}
}
获取Tree的图片#region 获取Tree的图片
string GetTreeNodeImg(DataRow dr, bool isLeaf, bool isBottom)
{
return GetTreeNodeOtherImg(dr) + GetTreeNodeLastImg(isLeaf, isBottom);
}
string GetTreeNodeOtherImg(DataRow dr)
{
if (dr["TreeListView$Row$ParentRow"] != null&&!dr["TreeListView$Row$ParentRow"].Equals(DBNull.Value))
{
DataRow drParentRow = dr["TreeListView$Row$ParentRow"] as DataRow;
bool parentIsBottom = Convert.ToBoolean(drParentRow["TreeListView$Row$IsBottom"]);
if (parentIsBottom)
{
return GetTreeNodeOtherImg(drParentRow) + string.Format("<img src={0} align=absmiddle>", TreeListView.TreeImageFolder + "white.gif");
}
else
{
return GetTreeNodeOtherImg(drParentRow) + string.Format("<img src={0} align=absmiddle>", TreeListView.TreeImageFolder + "i.gif");
}
}
else
{
return string.Empty;
}
}
string GetTreeNodeLastImg(bool isLeaf, bool isBottom)
{
//最后靠近的那个Image
string lastImg = string.Empty;
if (isLeaf)
{
if (isBottom)
{
lastImg = string.Format("<img src={0} align=absmiddle>", TreeListView.TreeImageFolder + "l.gif");
}
else
{
lastImg = string.Format("<img src={0} align=absmiddle>",TreeListView.TreeImageFolder + "t.gif");
}
}
else
{
if (isBottom)
{
lastImg = string.Format("<img src={0} align=absmiddle οnclick='ClickNode(this,true,\"{1}\");' style=\"cursor: hand\">", TreeListView.TreeImageFolder + "lminus.gif", this.Parent.Parent.ClientID);
}
else
{
lastImg = string.Format("<img src={0} align=absmiddle οnclick='ClickNode(this,true,\"{1}\");' style=\"cursor: hand\">", TreeListView.TreeImageFolder + "tminus.gif", this.Parent.Parent.ClientID);
}
}
return lastImg;
}
#endregion
Js代码实现折叠效果
var lExpend = "lminus.gif";
var lPinch = "lplus.gif";
var tExpend = "tminus.gif";
var tPinch = "tplus.gif";
function ClickNode(img,isBottom,tableId)
{
var imgId = img.src.substring(img.src.lastIndexOf("/")+1);
var url = img.src.substring(0,img.src.lastIndexOf("/")+1);
var oldTrId = img.parentElement.parentElement.id;
var newTrId = oldTrId.substring(oldTrId.indexOf("_")+1);
if( isBottom)
{
if( imgId == lExpend)
{
img.src = url+ lPinch;
img.parentElement.id = lPinch;
PinchNode(newTrId,oldTrId,tableId);
}
else
{
img.src = url + lExpend;
img.parentElement.id = lExpend;
ExpendNode(newTrId,oldTrId,tableId);
}
}
else
{
if( imgId == tExpend )
{
img.src = url+ tPinch;
img.parentElement.id = tPinch;
PinchNode(newTrId,oldTrId,tableId);
}
else
{
img.src = url + tExpend;
img.parentElement.id = tExpend;
ExpendNode(newTrId,oldTrId,tableId);
}
}
}
function ExpendNode(newId,oldId,tableId)
{
var tree = document.getElementById(tableId);
for( var i = 0; i < tree.rows.length; i++ )
{
if( tree.rows[i].id.indexOf(newId) != -1 && tree.rows[i].id != oldId )
{
var isExpend = true;
var pId = tree.rows[i].id;
while( pId != oldId)
{
for( var j = 0; j < 2; j++ )
pId = pId.substring( 0,pId.lastIndexOf("/"));
var parent = document.getElementById(pId);
if( parent != null )
{
var tempId = parent.cells[2].id;
if( tempId == lExpend || tempId == tExpend || tempId == "")
;
else
{
isExpend = false;
break;
}
}
else
break;
}
if( isExpend )
tree.rows[i].style.display="block";
}
}
}
function PinchNode(newId,oldId,tableId)
{
var tree = document.getElementById(tableId);
for( var i = 0; i < tree.rows.length; i++ )
{
if( tree.rows[i].id.indexOf(newId) != -1 && tree.rows[i].id != oldId)
{
tree.rows[i].style.display = "none";
}
}
}
转载于:https://www.cnblogs.com/wschacker/archive/2008/07/24/1250446.html
支持树型的GridView控件相关推荐
- Delphi 7下使用VT实现树型列表结合控件
Delphi 7下使用VT实现树型列表结合控件 转载于:https://www.cnblogs.com/LittleTiger/p/5007580.html
- GridView控件详解
GridView是ASP.NET 1.x的DataGrid控件的后继者.它提供了相同的基本功能集,同时增加了大量扩展和改进.如前所述,DataGrid(ASP.NET 2.0仍然完全支持)是一个功能非 ...
- 扩展GridView控件——为内容项添加拖放及分组功能
引言 相信大家对GridView都不陌生,是非常有用的控件,用于平铺有序的显示多个内容项.打开任何WinRT应用或者是微软合作商的网站,都会在APP中发现GridView的使用."Tiles ...
- 自学Web开发第十四天-基于VB和ASP.NET;丰富数据呈现:TreeView控件的使用及与GridView控件联动,深入研究从GridView中取数据
自学Web开发第十四天-基于VB和ASP.NET:丰富数据呈现:TreeView控件的使用及与GridView控件联动,深入研究从GridView中取数据 GridView操作数据库后,刷新TreeV ...
- 在 GridView 控件中添加一列复选框51
简介 在前面的教程中 , 我们学习了如何为 GridView 控件添加一列 单选 按钮来选择一个特定的记录.当用户被限制最多只能从网格中选中一项时,一列单选按钮是一个非常恰当的用户界面.然而,有时我们 ...
- 使用ASP.NET 2.0中的GridView控件
在ASP.NET 2.0中,加入了许多新的功能和控件,相比asp.net 1.0/1.1,在各方面都有了很大的提高.其中,在数据控件方面,增加了不少控件,其中的gridview控件功能十分强大.在本文 ...
- 扩展GridView控件(2) - 复合排序和排序状态提示
GridView既强大又好用.为了让它更强大.更好用,我们来写一个继承自GridView的控件. [索引页] [源码下载] 扩展GridView控件(2) - 复合排序和排序状态提示 作者:webab ...
- C#中GridView控件的使用
C#中GridView控件的使用 一.GridView和DataGrid的异同 GridView 是 DataGrid的后继控件,在 framework 2中,虽然还存在DataGrid,但是Grid ...
- 【ASP.NET】第八课——GridView 控件的编辑功能优化,GridView控件中嵌套DropDownList控件
知识点:掌握 GridView 的编辑.高亮显示的功能 .GridView控件中嵌套DropDownList控件获取数据源. [ASP.NET]第七课--数据绑定和 GridView 控件的使用 重点 ...
- [GridView控件]事件详解
GridView是一个非常强大的控件,它支持分页,排序等等,我想每个人都应该用过这个控件,最近有个网友问了我一些问题,平时也没多大的注意,只要能满足自己的一些需求就没有深入的研究.通过了一段时间的研究 ...
最新文章
- 调用个别f5 负载端口为80的vs时,返回值为空的问题
- windows 导出 oracle,windows 环境下oracle导入导出
- 微信小程序连接阿里云物联网
- SocketLog-微信调试、API调试和AJAX的调试的工具,能将日志通过WebSocket输出到Chrome浏览器的console中
- netstat命令使用范例
- C#中的继承与多态还有接口
- (2021年)IT技术分享社区个人文章汇总(电脑技巧篇)
- 95-10-092-启动-TokenManager
- python函数的使用方法_Python函数使用
- Mysql学习总结(68)——MYSQL统计每天、每周、每月、每年数据 SQL 总结
- oracle字符串处理substr、dbms_lob.substr、case when
- Togu Audio Line推出最新版本的TAL-BassLine-101插件 支持M1芯片
- 阶段3 2.Spring_02.程序间耦合_1 编写jdbc的工程代码用于分析程序的耦合
- 【翻译】Adaptive Convolutions for Structure-Aware Style Transfer
- stokes方程matlab,【Fluent】雷诺方程:推导与求解(附MATLAB代码)
- CentOS 7.5 安装MySQL教程
- html中斜体样式怎么写,html i 斜体标签
- 如何给 SAP Commerce Cloud Site 设置默认语言
- linux 内存 参数,linux free命令参数及用法详解(linux查看内存命令)
- 《易语言百集教程》百集高清教程免费下载地址————【Badboy】
热门文章
- c#json对象转数组_C#中将json字符串转为List数组对象
- bigdecimal js 判断等于0_Js BigDecimal实现精确加减乘除运算的方法
- webview是什么东西_做性能优化前需要考虑什么?
- SpringMCV结构
- 推荐系统 | 信息过载的大数据时代,大数据推荐系统如何搭建,趋势何方
- Vue实现简单Tab标签页组件
- 网络是怎样连接的笔记第5章 防火墙,缓存服务器
- Libcurl的编译_HTTP/HTTPSclient源代码演示样例
- My97 DatePicker 选择时间后弹出选择的时间
- geotrellis使用(七)记录一次惨痛的bug调试经历以及求DEM坡度实践