AjaxPro.NET框架生成高效率的Tree(Asp.net 2.0)(示例代码下载)
(一). 说明
用Tree显示菜单及物品列表(从服务端获取数据)比较方便, 当前显示Tree 主要有两种方式:
1. 在Tree初始化时将数据全部一次性从服务端获取, 获取完数据后页面展开或收缩时就不再需要获取数据,这样, 获取完数据使用时效率比较高, 但当树节点很多时, 在每次初始化时会有较大的延迟.
2. 初始化时只加载展开的节点, 当用户需要查看某个节点下的数据时, 再去取数据, 这样, 初始化时延迟会相对减少, 但每次单击节点时要获取数据, 页面每次都要刷新, 所以也会产生延迟.
此事例用Ajax实现第二种方式, 每次只动态加载要展开的节点数据(闭合节点不展开时,则不获取其子节点的数据), 另外加载节点时页面不会刷新.
(二). 运行示例图


(三). AjaxPro.NET简介
var returnValue = 后台代码类名.GetSearchItems(参数);
2. 页面后台文件 Tree.aspx.cs 代码:
用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>
4
3. 在要使用AjaxPro.NET框架的页面 *.aspx.cs 的 Page_Load事件中加如下代码:
2

3

4

1
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
就可以在客户端直接使用服务端方法, 非常方便, 客户端调用后台代码如下:
2

3

4

5

6

7

8

9

10


(五). 代码
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>
144

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

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
}

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148
