熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> .NET編程 >> 正文

.net開發中的支持樹型的GridView控件

2013-11-13 10:04:24  來源: .NET編程 

  支持樹型的GridView

  實現思路 繼承自Gridview處理gridview的數據源使其在幫定時就已經按照樹型菜單順序排列好那樣只需在幫定處理其圖片是javascript腳本就可以了

  源代碼下載

  效果圖

    using System;
    using SystemData;
    using SystemCollections;
    using SystemCollectionsSpecialized;
    using SystemCollectionsGeneric;
    using SystemComponentModel;
    using SystemText;
    using SystemWeb;
    using SystemIO;
    using SystemDrawing;
    using SystemDrawingDesign;
    using SystemReflection;
    using SystemWebUI;
    using SystemWebUIWebControls;
    using SystemWebUIHtmlControls;
    [ToolboxData(<{}:TreeListView runat=server></{}:TreeListView>) DefaultProperty(Text)]
    public class TreeListView : GridView IPostBackDataHandler
    {
        public TreeListView()
        {
            baseAllowPaging = false;
            baseAllowSorting = false;
            baseAutoGenerateColumns = 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 baseDataSource;
            }
            set
            {
                DataTable dtSource = new DataTable();
                if (value is DataSet && ((DataSet)value)TablesCount > )
                {
                    DataSet ds = value as DataSet;
                    dtSource = OrderData(dsTables[]);
                }
                else
                {
                    throw new Exception(DataSource is not DataSet!);
                }
                baseDataSource = dtSource;
            }
        }

  DataTable OrderData(DataTable dtSource)
        {
            DataTable dtResult = dtSourceClone();
            dtResultColumnsAdd(TreeListView$Row$Depth typeof(int));
            dtResultColumnsAdd(TreeListView$Row$IsLeaf typeof(bool));
            dtResultColumnsAdd(TreeListView$Row$IsBottom typeof(bool));
            dtResultColumnsAdd(TreeListView$Row$ParentRow typeof(DataRow));
            dtResultColumnsAdd(TreeList$ViewRow$ClientID typeof(string));
            RecursionOrderData(dtSource dtResult _rootNodeFlag null);
            return dtResult;
        }
        string FormatToRowFilter(object val)
        {
            Type type = valGetType();
            if (type == typeof(string))
            {
                return stringFormat({} valToString()Replace( ));
            }
            else if (type == typeof(Guid))
            {
                return stringFormat({} val);
            }
            else if (typeIsValueType)
            {
                return valToString();
            }
            else
            {
                return stringFormat({} valToString()Replace( ));
            }
        }
        bool RecursionOrderData(DataTable dtSource DataTable dtResult object parentID int depth DataRow parentDatarow)
        {
            DataView dv = new DataView(dtSource);
            dvRowFilter = stringFormat({}={} _parentKey FormatToRowFilter(parentID));
            dvSort = _sortKey;
            DataRow dr = null;
            depth++;
            for (int i = ; i < dvCount; i++)
            {
                dr = dtResultNewRow();

  for (int j = ; j < dv[i]RowItemArrayLength; j++)
                {
                    dr[j] = dv[i][j];
                }

  if (i == dvCount ) //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] = GuidNewGuid()ToString();
                }
                else
                {
                    dr[TreeList$ViewRow$ClientID] = parentDatarow[TreeList$ViewRow$ClientID]ToString() + / + GuidNewGuid()ToString();
                }

  dtResultRowsAdd(dr);
                dr[TreeListView$Row$IsLeaf] = !RecursionOrderData(dtSource dtResult dv[i][_columnKey] depth dr);
            }

  return dvCount > ;
        }

  public override bool AllowPaging
        {
            get
            {
                return baseAllowPaging;
            }
            set
            {
                baseAllowPaging = false;
            }
        }

  public override bool AutoGenerateColumns
        {
            get
            {
                return baseAutoGenerateColumns;
            }
            set
            {
                baseAutoGenerateColumns = 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 < baseRowsCount; i++)
                {
                    _rowsArrayAdd((TreeListViewRow)baseRows[i]);
                }
                this_rowsCollection = new TreeListViewRowCollection(_rowsArray);
                return this_rowsCollection;
            }
        }
        #endregion

  重載:OnInit#region 重載:OnInit
        protected override void OnInit(EventArgs e)
        {
            baseOnInit(e);
            PageRegisterRequiresPostBack(this);

  if (!PageClientScriptIsClientScriptIncludeRegistered(JS_TreeListView))
            {
                thisPageClientScriptRegisterClientScriptInclude(thisGetType() JS_TreeListView PageClientScriptGetWebResourceUrl(thisGetType() GoldMantisWebUIResourceTreeListViewJS_TreeListViewjs));
            }
        }
        #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 (!thisShowHeader && !thisShowFooter)
            {
                return;
            }

  foreach (DataControlField field in Columns)
            {
                if (field is CheckBoxExField)
                {
                    int checkBoxExFieldIndex = ColumnsIndexOf(field) + thisGetAutoGenerateButtonCount();
                    foreach (GridViewRow row in Rows)
                    {
                        if (rowRowType == DataControlRowTypeHeader)
                        {
                            rowCells[checkBoxExFieldIndex]ControlsClear();
                        }
                        if (rowRowType == DataControlRowTypeDataRow)
                        {
                            rowCells[checkBoxExFieldIndex]Controls[]ID = cbChoose;
                            ((CheckBox)rowCells[checkBoxExFieldIndex]Controls[])AttributesAdd(onclick ChooseTree(this););
                        }
                    }

  注冊腳本#region 注冊腳本
                    string script = @
    var modifyId = ;
    var choosedId = ;
    var choosedIndex;
    function ChooseTree(obj)
    {
        var cTrId = objparentElementparentElementparentElementid;
        var treeTable = documentgetElementById(+thisClientID+@);
        for( var i = ; i < treeTablerowslength; i++ )
        {
            if( treeTablerows[i]idindexOf(cTrId) != && treeTablerows[i]id != cTrId )
            {
                documentgetElementById(treeTablerows[i]id+_cbChoose)checked = objchecked;
            }
        }
        choosedId = ;
        choosedIndex = new Array();
        for( var i = ; i < treeTablerowslength; i++ )
        {
            if( documentgetElementById(treeTablerows[i]id+_cbChoose)checked )
            {
                choosedId += treeTablerows[i]idsubstring(treeTablerows[i]idlastIndexOf(/)+) + ;
                choosedIndexpush(i);
            }
        }
       
        choosedId = choosedIdsubstring(choosedIdlength);
    };
                    if (!PageClientScriptIsStartupScriptRegistered(TreeListView_CheckBoxExField))
                    {
                        PageClientScriptRegisterStartupScript(GetType() TreeListView_CheckBoxExField script true);
                    }
                    #endregion
                }
            }
        }
        方法:GetAutoGenerateButtonCount#region 方法:GetAutoGenerateButtonCount
        private int GetAutoGenerateButtonCount()
        {
            int num = ;
            if (thisAutoGenerateDeleteButton || thisAutoGenerateEditButton || thisAutoGenerateSelectButton)
            {
                num = ;
            }
            return num;
        }
        #endregion
        #endregion

  protected override void Render(HtmlTextWriter writer)
        {
            RenderCheckBoxExField();
            baseRender(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)
        {
            baseOnPreRender(e);
            if (thisRowType == DataControlRowTypeDataRow)
            {
                if (thisParentParent is TreeListView)
                {
                    TreeListView treeListView = thisParentParent as TreeListView;
                    DataRow dr = ((DataTable)treeListViewDataSource)Rows[thisDataItemIndex] as DataRow;
                    string str = GetTreeNodeImg(dr ConvertToBoolean(dr[TreeListView$Row$IsLeaf]) ConvertToBoolean(dr[TreeListView$Row$IsBottom]));
                    thisCells[treeListViewNodeColumnIndex]Text = str + thisCells[treeListViewNodeColumnIndex]Text;
                    thisID = dr[TreeList$ViewRow$ClientID]ToString();
                    if (treeListViewExpendDepth > )
                    {
                        thisStyle[display] = treeListViewExpendDepth >= ConvertToInt(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(DBNullValue))
            {
                DataRow drParentRow = dr[TreeListView$Row$ParentRow] as DataRow;
                bool parentIsBottom = ConvertToBoolean(drParentRow[TreeListView$Row$IsBottom]);
                if (parentIsBottom)
                {
                    return GetTreeNodeOtherImg(drParentRow) + stringFormat(<img src={} align=absmiddle> TreeListViewTreeImageFolder + whitegif);
                }
                else
                {
                    return GetTreeNodeOtherImg(drParentRow) + stringFormat(<img src={} align=absmiddle> TreeListViewTreeImageFolder + igif);
                }

  }
            else
            {
                return stringEmpty;
            }
        }
        string GetTreeNodeLastImg(bool isLeaf bool isBottom)
        {
            //最後靠近的那個Image
            string lastImg = stringEmpty;
            if (isLeaf)
            {
                if (isBottom)
                {
                    lastImg = stringFormat(<img src={} align=absmiddle> TreeListViewTreeImageFolder + lgif);
                }
                else
                {
                    lastImg = stringFormat(<img src={} align=absmiddle>TreeListViewTreeImageFolder + tgif);
                }
            }
            else
            {
                if (isBottom)
                {
                    lastImg = stringFormat(<img src={} align=absmiddle onclick=ClickNode(thistrue\{}\); style=\cursor: hand\> TreeListViewTreeImageFolder + lminusgif thisParentParentClientID);
                }
                else
                {
                    lastImg = stringFormat(<img src={} align=absmiddle onclick=ClickNode(thistrue\{}\); style=\cursor: hand\> TreeListViewTreeImageFolder + tminusgif thisParentParentClientID);
                }
            }
            return lastImg;

  }
        #endregion

  Js代碼實現折疊效果

  Code

    

  var lExpend = lminusgif;
var lPinch = lplusgif;  
var tExpend = tminusgif;
var tPinch = tplusgif;        

  function ClickNode(imgisBottomtableId)
{
    var imgId = imgsrcsubstring(imgsrclastIndexOf(/)+);
    var url = imgsrcsubstring(imgsrclastIndexOf(/)+);
    var oldTrId = imgparentElementparentElementid;
    var newTrId = oldTrIdsubstring(oldTrIdindexOf(_)+);
   
    if( isBottom)
    {
        if( imgId == lExpend)
        {
            imgsrc =  url+ lPinch;
            imgparentElementid = lPinch;
            PinchNode(newTrIdoldTrIdtableId);
        }
        else
        {
            imgsrc = url + lExpend;
            imgparentElementid = lExpend;
            ExpendNode(newTrIdoldTrIdtableId);
        }  
    }
    else
    {
        if( imgId == tExpend )
        {
            imgsrc =  url+ tPinch;
            imgparentElementid = tPinch;
            PinchNode(newTrIdoldTrIdtableId);
     
        }
        else
        {
            imgsrc = url + tExpend;
            imgparentElementid = tExpend;
            ExpendNode(newTrIdoldTrIdtableId);
        }  
    }
}

  function ExpendNode(newIdoldIdtableId)
{
    var tree = documentgetElementById(tableId);
    for( var i = ; i < treerowslength; i++ )
    {
        if( treerows[i]idindexOf(newId) != && treerows[i]id != oldId )
        {
            var isExpend = true;
            var pId = treerows[i]id;
          
            while( pId != oldId)
            {
                for( var j = ; j < ; j++ )
                    pId = pIdsubstring( pIdlastIndexOf(/));
                var parent = documentgetElementById(pId);
                if( parent != null )
                {
                    var tempId = parentcells[]id;
                    if( tempId == lExpend || tempId == tExpend || tempId == )
                        ;
                    else
                    {
                        isExpend = false;
                        break;
                    }
                }
                else
                    break;
            }
            if( isExpend )
               treerows[i]styledisplay=block
        }
    }
}

  function PinchNode(newIdoldIdtableId)
{
    var tree = documentgetElementById(tableId);
    for( var i = ; i < treerowslength; i++ )
    {
        if( treerows[i]idindexOf(newId) != && treerows[i]id != oldId)
        {
            treerows[i]styledisplay = none;
        }
    }
}


From:http://tw.wingwit.com/Article/program/net/201311/12471.html
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.