知识大全 .net开发中的支持树型的GridView控件
Posted 知
篇首语:知识是一种快乐,而好奇则是知识的萌芽。本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识大全 .net开发中的支持树型的GridView控件相关的知识,希望对你有一定的参考价值。
.net开发中的支持树型的GridView控件 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!
支持树型的GridView
实现思路 继承自Gridview 处理gridview的数据源 使其在帮定时 就已经按照树型菜单顺序排列好 那样只需在帮定处理其图片是javascript脚本就可以了
源代码下载
效果图
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( < :TreeListView runat=server></ :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 = ; /**//// <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 > ) DataSet ds = value as DataSet; dtSource = OrderData(ds Tables[ ]); 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 null); return dtResult; string FormatToRowFilter(object val) Type type = val GetType(); if (type == typeof(string)) return string Format( val ToString() Replace( )); else if (type == typeof(Guid)) return string Format( val); else if (type IsValueType) return val ToString(); else return string Format( val ToString() Replace( )); bool RecursionOrderData(DataTable dtSource DataTable dtResult object parentID int depth DataRow parentDatarow) DataView dv = new DataView(dtSource); dv RowFilter = string Format( = _parentKey FormatToRowFilter(parentID)); dv Sort = _sortKey; DataRow dr = null; depth++; for (int i = ; i < dv Count; i++) dr = dtResult NewRow();
for (int j = ; j < dv[i] Row ItemArray Length; j++) dr[j] = dv[i][j];
if (i == dv Count ) //isBottom dr[ TreeListView$Row$IsBottom ] = true; else dr[ TreeListView$Row$IsBottom ] = false; dr[ TreeListView$Row$Depth ] = depth; dr[ TreeListView$Row$ParentRow ] = parentDatarow; if (depth == ) 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 > ;
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 = ; 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[ ] ID = cbChoose ; ((CheckBox)row Cells[checkBoxExFieldIndex] Controls[ ]) 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 = ; i < treeTable rows length; i++ ) if( treeTable rows[i] id indexOf(cTrId) != && treeTable rows[i] id != cTrId ) document getElementById(treeTable rows[i] id+ _cbChoose ) checked = obj checked; choosedId = ; choosedIndex = new Array(); for( var i = ; 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( / )+ ) + ; choosedIndex push(i); choosedId = choosedId substring( choosedId length ); ; if (!Page ClientScript IsStartupScriptRegistered( TreeListView_CheckBoxExField )) Page ClientScript RegisterStartupScript(GetType() TreeListView_CheckBoxExField script true); #endregion 方法:GetAutoGenerateButtonCount#region 方法:GetAutoGenerateButtonCount private int GetAutoGenerateButtonCount() int num = ; if (this AutoGenerateDeleteButton || this AutoGenerateEditButton || this AutoGenerateSelectButton) num = ; return num; #endregion #endregion
protected override void Render(HtmlTextWriter writer) RenderCheckBoxExField(); base Render(writer);
public class TreeListViewRow : GridViewRow 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 > ) this Style[ display ] = treeListView ExpendDepth >= Convert ToInt (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= align=absmiddle> TreeListView TreeImageFolder + white gif ); else return GetTreeNodeOtherImg(drParentRow) + string Format( <img src= 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= align=absmiddle> TreeListView TreeImageFolder + l gif ); else lastImg = string Format( <img src= align=absmiddle> TreeListView TreeImageFolder + t gif ); else if (isBottom) lastImg = string Format( <img src= align=absmiddle onclick= ClickNode(this true \\ \\ ); style=\\ cursor: hand\\ > TreeListView TreeImageFolder + lminus gif this Parent Parent ClientID); else lastImg = string Format( <img src= align=absmiddle onclick= ClickNode(this true \\ \\ ); style=\\ cursor: hand\\ > TreeListView TreeImageFolder + tminus gif this Parent Parent ClientID); return lastImg;
#endregion
Js代码实现折叠效果
Code
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( / )+ ); var url = img src substring( img src lastIndexOf( / )+ ); var oldTrId = img parentElement parentElement id; var newTrId = oldTrId substring(oldTrId indexOf( _ )+ ); 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 = ; i < tree rows length; i++ ) if( tree rows[i] id indexOf(newId) != && tree rows[i] id != oldId ) var isExpend = true; var pId = tree rows[i] id; while( pId != oldId) for( var j = ; j < ; j++ ) pId = pId substring( pId lastIndexOf( / )); var parent = document getElementById(pId); if( parent != null ) var tempId = parent cells[ ] 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 = ; i < tree rows length; i++ ) if( tree rows[i] id indexOf(newId) != && tree rows[i] id != oldId) tree rows[i] style display = none ;
cha138/Article/program/net/201311/12471相关参考
知识大全 ASP.NET入门教程 7.4.2 GridView控件[3]
ASP.NET入门教程7.4.2GridView控件[3] 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一
知识大全 ASP.NET入门教程 7.4.2 GridView控件[2]
ASP.NET入门教程7.4.2GridView控件[2] 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一
知识大全 ASP.NET入门教程 7.4.2 GridView控件[1]
ASP.NET入门教程7.4.2GridView控件[1] 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一
为ASP.NET控件添加设计时支持 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!Microsoft
Asp.net控件开发----控件开发基础 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 服务器
控件的显示自然会离不开输出HTMLCSSJavascript等前台的显示内容所以开发一个控件的时候第一件事就是要知道如何输出客户端要显示的内容 一选择基类 中所有的标准控件都可以拿过来作为基类
控件的显示自然会离不开输出cssjavascript等前台的显示内容所以开发一个控件的时候第一件事就是要知道如何输出客户端要显示的内容一选择基类 &n
ASP.NET控件开发基础之复合控件事件处理浅析 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!
分析ASP.NET服务器控件开发-控件生命周期 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!&nb
使用VB.NET开发定制控件 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 正常情况下在开发NET