高效率Tree

(一). 说明

下载代码
用Tree显示菜单及物品列表(从服务端获取数据)比较方便, 当前显示Tree 主要有两种方式:

        1. 在Tree初始化时将数据全部一次性从服务端获取, 获取完数据后页面展开或收缩时就不再需要获取数据,          

            这样, 获取完数据使用时效率比较高, 但当树节点很多时, 在每次初始化时会有较大的延迟.

        2. 初始化时只加载展开的节点, 当用户需要查看某个节点下的数据时, 再去取数据, 这样, 初始化时延迟会相

            对减少, 但每次单击节点时要获取数据, 页面每次都要刷新, 所以也会产生延迟.

        此事例用Ajax实现第二种方式, 每次只动态加载要展开的节点数据(闭合节点不展开时,则不获取其子节点的

        数据),  另外加载节点时页面不会刷新.

(二). 运行示例图

(三). AjaxPro.NET简介

         首先对AjaxPro.NET作一下介绍, AjaxPro.NET是一个优秀的Ajax框架, 在实际应用中只要添加其DLL

         引用并进行简单的配置, 即可以非常方便的在客户端直接调用服务端方法, 来获取Tree节点.

(四).使用AjaxPro.NET预配置

       1. 添加 AjaxPro.dll 文件的引用(示例代码中已经包含,直接COPY过来使用即可).

       2. 在Web.config文件中添加以下配置,           

1 <httpHandlers>
2             <add verb="POST,GET" path="ajaxpro/*.ashx" type="AjaxPro.AjaxHandlerFactory, AjaxPro" />            
3 </httpHandlers>
 
 
       3. 在要使用AjaxPro.NET框架的页面 *.aspx.cs 的 Page_Load事件中加如下代码:
 
AjaxPro.Utility.RegisterTypeForAjax(typeof(_Default));
 
       4. 经过以上三步骤后, 只要在后台服务端的方法前面增加属性[AjaxMethod]后:
 
 1  [AjaxMethod()]    // or [AjaxPro.AjaxMethod] 
 2 public ArrayList GetSearchItems( string strQuery )
 3 {
 4      //生成数据源
 5      ArrayList items = new ArrayList();
 6      items.Add("King");
 7      items.Add("Rose");
 8      return items ;
 9 
10 
 
        就可以在客户端直接使用服务端方法, 非常方便, 客户端调用后台代码如下:
var returnValue = 后台代码类名.GetSearchItems(参数);

(五). 代码

  1. 页面 Tree.aspx 代码:

  1 <%@ Page Language="C#" AutoEventWireup="true"  CodeFile="Tree.aspx.cs" Inherits="_Default" %>
  2 
  3 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  4 
  5 <html xmlns="http://www.w3.org/1999/xhtml" >
  6 <head runat="server">
  7     <title>Ajax Efficient Tree</title>
  8     <link type="text/css" href="css/tree.css" rel="stylesheet">
  9 </head>
 10 <body>
 11     <form id="form1" runat="server">
 12     <div>
 13         <asp:Panel ID="Panel1" runat="server" Height="424px" Width="251px">
 14             <div id="CategoryTree" class="TreeMenu"></div>
 15         </asp:Panel>
 16         <script language="jscript">
 17             var tree = document.getElementById("CategoryTree");
 18             var root = document.createElement("li");
 19             root.id = "li_0";
 20             tree.appendChild( root );
 21             ExpandSubCategory( 0 );
 22             function ExpandSubCategory( categoryID )
 23             {
 24                 var liFather = document.getElementById( "li_" + categoryID );
 25                 if( liFather.getElementsByTagName("li").length > 0)
 26                 {
 27                     ChangeStatus( categoryID );
 28                     return;
 29                 }
 30                 liFather.className = "Opened";
 31                 SwitchNode( categoryID, true );
 32                 
 33                 //仅获取当前节点的子Nodes
 34                 _Default.GetSubCategory( categoryID, GetSubCategory_callback );
 35             }            
 36             function SwitchNode( CategoryID, show )
 37             {
 38                 var li_father = document.getElementById("li_" + CategoryID);
 39                 if( show )
 40                 {
 41                     var ul = document.createElement("ul");
 42                     ul.id = "ul_note_" + CategoryID;
 43                     
 44                     var note = document.createElement("li");
 45                     note.className = "Child";              
 46                     
 47                     var img = document.createElement("img");
 48                     img.className = "s";
 49                     img.src = "css/s.gif";                    
 50                     
 51                     var a = document.createElement("a");
 52                     a.href = "javascript:void(0);";
 53                     a.innerHTML = "Please waiting";
 54                     
 55                     note.appendChild(img);
 56                     note.appendChild(a);
 57                     ul.appendChild(note);
 58                     li_father.appendChild(ul);                                        
 59                 }   
 60                 else
 61                 {
 62                     var ul = document.getElementById("ul_note_" + CategoryID );
 63                     if( ul )
 64                     {
 65                         li_father.removeChild(ul);
 66                     }
 67                 }             
 68             }
 69             function GetSubCategory_callback( response )
 70             {
 71                var dt = response.value.Tables[0];
 72                if( dt.Rows.length > 0 )
 73                {
 74                     var iCategoryID = dt.Rows[0].FatherID;               
 75                }                                
 76                var li_father = document.getElementById("li_" + iCategoryID );
 77                var ul = document.createElement("ul");
 78                for( var i = 0; i < dt.Rows.length; i++ )
 79                {
 80                     if( dt.Rows[i].IsChild == 1 )
 81                     {
 82                         var li = document.createElement("li");
 83                         li.className = "Child";
 84                         li.id = "li_" + dt.Rows[i].CategoryID;
 85                         var img = document.createElement("img");
 86                         img.id = dt.Rows[i].CategoryID;
 87                         img.className = "s";
 88                         img.src = "css/s.gif";
 89                         var a = document.createElement("a");
 90                         a.href = "javascript:OpenDocument('" + dt.Rows[i].CategoryID + "');";
 91                         a.innerHTML = dt.Rows[i].CategoryName;                                          
 92                     }
 93                     else
 94                     {
 95                         var li = document.createElement("li");
 96                         li.className = "Closed";
 97                         li.id = "li_" + dt.Rows[i].CategoryID;
 98                         var img = document.createElement("img");
 99                         img.id = dt.Rows[i].CategoryID;
100                         img.className = "s";
101                         img.src = "css/s.gif";
102                         img.onclick = function(){ ExpandSubCategory( this.id ); };
103                         img.alt = "Expand/collapse";
104                         var a = document.createElement("a");
105                         a.href = "javascript:ExpandSubCategory('" + dt.Rows[i].CategoryID + "');";
106                         a.innerHTML = dt.Rows[i].CategoryName;                                         
107                     }
108                     li.appendChild(img);
109                     li.appendChild(a);
110                     ul.appendChild(li);
111                }
112                li_father.appendChild(ul);
113                SwitchNode( iCategoryID, false );
114             }          
115             
116             //单击叶节点时, 异步从服务端获取单个节点的数据.
117             function OpenDocument( CategoryID )
118             {                
119                 _Default.GetNameByCategoryID( CategoryID, GetNameByCategoryID_callback );
120             }
121             
122             function GetNameByCategoryID_callback( response )
123             {
124                 alert( response.value );
125             }
126             
127             function ChangeStatus( CategoryID )
128             {
129                 var li_father = document.getElementById("li_" + CategoryID );
130                 if( li_father.className == "Closed" )
131                 {
132                     li_father.className = "Opened";
133                 }
134                 else
135                 {
136                     li_father.className = "Closed";
137                 }
138            }              
139         </script>          
140     </div>
141     </form>    
142 </body>      
143 </html>

 2. 页面后台文件 Tree.aspx.cs 代码:

  1 using System;
  2 using System.Data;
  3 using System.Configuration;
  4 using System.Web;
  5 using System.Web.Security;
  6 using System.Web.UI;
  7 using System.Web.UI.WebControls;
  8 using System.Web.UI.WebControls.WebParts;
  9 using System.Web.UI.HtmlControls;
 10 
 11 public partial class _Default : System.Web.UI.Page 
 12 {
 13    //此对象用于存放所有的节点数
 14    public static DataSet dsAllNodes = new DataSet();
 15 
 16    protected void Page_Load(object sender, EventArgs e)
 17    {
 18        AjaxPro.Utility.RegisterTypeForAjax(typeof(_Default));       
 19        CreateNodes();
 20    }
 21 
 22    private DataTable CreateStructure()
 23    {
 24       DataTable dt = new DataTable();
 25       dt.Columns.Add(new DataColumn("CategoryID"typeof(int)));
 26       dt.Columns.Add(new DataColumn("CategoryName"typeof(string)));
 27       dt.Columns.Add(new DataColumn("FatherID"typeof(string)));
 28       dt.Columns.Add(new DataColumn("IsChild"typeof(bool)));
 29       return dt;
 30    }
 31    public void CreateNodes()
 32    {
 33       DataTable dt = this.CreateStructure();
 34 
 35       DataRow drNew = dt.NewRow();
 36       drNew["CategoryID"= 1;
 37       drNew["CategoryName"= "物品类别";
 38       drNew["FatherID"= 0;
 39       dt.Rows.Add( drNew );
 40 
 41       drNew = dt.NewRow();
 42       drNew["CategoryID"= 2;
 43       drNew["CategoryName"= "水果";
 44       drNew["FatherID"= 1;
 45       dt.Rows.Add( drNew );
 46 
 47       drNew = dt.NewRow();
 48       drNew["CategoryID"= 3;
 49       drNew["CategoryName"= "工具";
 50       drNew["FatherID"= 1;
 51       dt.Rows.Add( drNew );
 52 
 53       drNew = dt.NewRow();
 54       drNew["CategoryID"= 4;
 55       drNew["CategoryName"= "萍果";
 56       drNew["FatherID"= 2;
 57       dt.Rows.Add( drNew );
 58 
 59       drNew = dt.NewRow();
 60       drNew["CategoryID"= 5;
 61       drNew["CategoryName"= "香蕉";
 62       drNew["FatherID"= 2;
 63       dt.Rows.Add( drNew );
 64 
 65       drNew = dt.NewRow();
 66       drNew["CategoryID"= 6;
 67       drNew["CategoryName"= "桔子";
 68       drNew["FatherID"= 2;
 69       dt.Rows.Add( drNew );
 70 
 71       drNew = dt.NewRow();
 72       drNew["CategoryID"= 7;
 73       drNew["CategoryName"= "萝卜";
 74       drNew["FatherID"= 2;
 75       dt.Rows.Add( drNew );
 76 
 77       drNew = dt.NewRow();
 78       drNew["CategoryID"= 8;
 79       drNew["CategoryName"= "钢笔";
 80       drNew["FatherID"= 3;
 81       dt.Rows.Add( drNew );
 82 
 83       drNew = dt.NewRow();
 84       drNew["CategoryID"= 9;
 85       drNew["CategoryName"= "铅笔";
 86       drNew["FatherID"= 3;
 87       dt.Rows.Add( drNew );
 88 
 89       drNew = dt.NewRow();
 90       drNew["CategoryID"= 10;
 91       drNew["CategoryName"= "尺子";
 92       drNew["FatherID"= 3;
 93       dt.Rows.Add( drNew );
 94       
 95       drNew = dt.NewRow();
 96       drNew["CategoryID"= 11;
 97       drNew["CategoryName"= "橡皮";
 98       drNew["FatherID"= 3;
 99       dt.Rows.Add( drNew );
100 
101       dsAllNodes.Tables.Add(dt);
102    }
103 
104    [AjaxPro.AjaxMethod]
105    public DataSet GetSubCategory(int CategoryID)
106    {
107       DataSet ds = new DataSet();
108       DataTable dt = this.CreateStructure();
109       DataRow[] drSelect = dsAllNodes.Tables[0].Select("FatherID=" + CategoryID.ToString());
110       foreach (DataRow drTemp in drSelect)
111       {
112          DataRow dr = dt.NewRow();
113          dr["CategoryID"= drTemp["CategoryID"];
114          dr["CategoryName"= drTemp["CategoryName"];
115          dr["FatherID"= drTemp["FatherID"];
116          dr["IsChild"= IsLeaf( int.Parse( drTemp["CategoryID"].ToString() ) );
117          dt.Rows.Add(dr);
118       }
119       ds.Tables.Add(dt);
120       return ds;
121    }
122 
123    [AjaxPro.AjaxMethod]
124    public bool IsLeaf(int Category)
125    {
126        foreach(DataRow dr in dsAllNodes.Tables[0].Rows)
127        {
128           if (dr["FatherID"!= null && int.Parse(dr["FatherID"].ToString()) == Category)
129           {
130              return false;  
131           }
132        }
133        return true;
134    }
135 
136    [AjaxPro.AjaxMethod]
137    public string GetNameByCategoryID(string CategoryID )
138    {
139       foreach( DataRow dr in dsAllNodes.Tables[0].Rows )
140       {
141          if( dr["CategoryID"].ToString() == CategoryID.ToString() )
142          {
143             return dr["CategoryName"].ToString();
144          }
145       }
146       return "";
147    }
148 }
posted @ 2007-04-09 16:42  简单就好  阅读(3809)  评论(16编辑  收藏  举报