最近在使用ASP.net 2.0的GridView 控件时,发现排序与分页功能Microsoft实现的都很简单,比如排序,在点击列名的时候来触发整页的PostBack,然后排序,但是在列头上没有一个显示升序降序的图标,这会让最终用户使用时很迷惑,因为不知道是升序了还是降序了,所以今天首先解决的第一问题就是升序降序在列上显示图标,第二要解决的问题是默认GridView按列排序只能排一列的,也就是不能进行多列排序,而在实际应用中仅仅按照一列来排序是不能满足业务需求的,第三是GridView 分页问题,GridView预定义的分页页码显示,比较简单,而实际应用中,分页可能不是只显示首页,上一页,下一页,末页,或者是数字的页码那么简单,应该更需要,跳转,当前的页码,总页数等,更详尽的信息。
第一:GridView 多列排序与排序图标显示
首先我们可以新建一个类库程序,主要需要引用System.Web.Dll文件
然后新建一个类,这个类继承与GridView控件,我们只需要对部分方法进行重新即可。
我的演示的例子,采用了单列排序,如果启用多列排序,把控件的AllowMultiColumnSorting设置为True就是
多列排序。

<script runat="server">
void PageDropDownList_SelectedIndexChanged(Object sender, EventArgs e)

{
GridViewRow pagerRow = CustomersGridView.BottomPagerRow;
DropDownList pageList = (DropDownList)pagerRow.Cells[0].FindControl("PageDropDownList");
CustomersGridView.PageIndex = pageList.SelectedIndex;
}
void CustomersGridView_DataBound(Object sender, EventArgs e)

{
GridViewRow pagerRow = CustomersGridView.BottomPagerRow;

LinkButton linkBtnFirst = (LinkButton)pagerRow.Cells[0].FindControl("linkBtnFirst");
LinkButton linkBtnPrev = (LinkButton)pagerRow.Cells[0].FindControl("linkBtnPrev");
LinkButton linkBtnNext = (LinkButton)pagerRow.Cells[0].FindControl("linkBtnNext");
LinkButton linkBtnLast = (LinkButton)pagerRow.Cells[0].FindControl("linkBtnLast");

if (CustomersGridView.PageIndex == 0)

{
linkBtnFirst.Enabled = false;
linkBtnPrev.Enabled = false;
}
else if (CustomersGridView.PageIndex == CustomersGridView.PageCount-1)

{
linkBtnLast.Enabled = false;
linkBtnNext.Enabled = false;
}
else if (CustomersGridView.PageCount<=0)

{
linkBtnFirst.Enabled = false;
linkBtnPrev.Enabled = false;
linkBtnNext.Enabled = false;
linkBtnLast.Enabled = false;
}
DropDownList pageList = (DropDownList)pagerRow.Cells[0].FindControl("PageDropDownList");
Label pageLabel = (Label)pagerRow.Cells[0].FindControl("CurrentPageLabel");

if (pageList != null)

{
for (int i = 0; i < CustomersGridView.PageCount; i++)

{
int pageNumber = i + 1;
ListItem item = new ListItem(pageNumber.ToString() + "/" + CustomersGridView.PageCount.ToString(), pageNumber.ToString());
if (i == CustomersGridView.PageIndex)

{
item.Selected = true;
}
pageList.Items.Add(item);

}

}
if (pageLabel != null)

{
int currentPage = CustomersGridView.PageIndex + 1;
pageLabel.Text = "当前页: " + currentPage.ToString() +
" / " + CustomersGridView.PageCount.ToString();
}
}

</script>

<html>
<body>
<form id="Form1" runat="server">
<h3>
GridView PagerTemplate Example</h3>
<asp:WebGridView ID="CustomersGridView" DataSourceID="CustomersSqlDataSource" AutoGenerateColumns="true"
AllowPaging="true" OnDataBound="CustomersGridView_DataBound" SortAscImageUrl="~/images/arrow-up.gif" SortDescImageUrl="~/images/arrow-down.gif" runat="server" AllowSorting="True" Width="723px">
<PagerStyle ForeColor="Blue" BackColor="LightBlue" />
<PagerTemplate>
<table width="100%">
<tr>
<td width="70%">
<asp:Label ID="MessageLabel" ForeColor="Blue" Text="页码:" runat="server" />
<asp:DropDownList ID="PageDropDownList" AutoPostBack="true" OnSelectedIndexChanged="PageDropDownList_SelectedIndexChanged"
runat="server" />
<asp:LinkButton CommandName="Page" CommandArgument="First" ID="linkBtnFirst" runat="server">首页</asp:LinkButton>
<asp:LinkButton CommandName="Page" CommandArgument="Prev" ID="linkBtnPrev" runat="server">上一页</asp:LinkButton>
<asp:LinkButton CommandName="Page" CommandArgument="Next" ID="linkBtnNext" runat="server">下一页</asp:LinkButton>
<asp:LinkButton CommandName="Page" CommandArgument="Last" ID="linkBtnLast" runat="server">末页</asp:LinkButton>
</td>
<td width="70%" align="right">
<asp:Label ID="CurrentPageLabel" ForeColor="Blue" runat="server" />
</td>
</tr>
</table>
</PagerTemplate>
</asp:WebGridView>
<asp:SqlDataSource ID="CustomersSqlDataSource" SelectCommand="Select [CustomerID], [CompanyName], [Address], [City], [PostalCode], [Country] From [Customers]"
ConnectionString="<%$ ConnectionStrings:NorthWindConnectionString%>" runat="server">
</asp:SqlDataSource>

</form>
</body>
</html>

第一:GridView 多列排序与排序图标显示
首先我们可以新建一个类库程序,主要需要引用System.Web.Dll文件
然后新建一个类,这个类继承与GridView控件,我们只需要对部分方法进行重新即可。
我的演示的例子,采用了单列排序,如果启用多列排序,把控件的AllowMultiColumnSorting设置为True就是
多列排序。
1
public class WebGridView:GridView
2
{
3
属性#region 属性
4
/**//// <summary>
5
/// 是否启用或者禁止多列排序
6
/// </summary>
7
[
8
Description("是否启用多列排序功能"),
9
Category("排序"),
10
DefaultValue("false"),
11
]
12
public bool AllowMultiColumnSorting
13
{
14
get
15
{
16
object o = ViewState["EnableMultiColumnSorting"];
17
return (o != null ? (bool)o : false);
18
}
19
set
20
{
21
AllowSorting = true;
22
ViewState["EnableMultiColumnSorting"] = value;
23
}
24
}
25
/**//// <summary>
26
/// 升序时显示图标
27
/// </summary>
28
[
29
Description("升序时显示图标"),
30
Category("排序"),
31
Editor("System.Web.UI.Design.UrlEditor", typeof(System.Drawing.Design.UITypeEditor)),
32
DefaultValue(""),
33
34
]
35
public string SortAscImageUrl
36
{
37
get
38
{
39
object o = ViewState["SortImageAsc"];
40
return (o != null ? o.ToString() : "");
41
}
42
set
43
{
44
ViewState["SortImageAsc"] = value;
45
}
46
}
47
/**//// <summary>
48
/// 降序时显示图标
49
/// </summary>
50
[
51
Description("降序时显示图标"),
52
Category("排序"),
53
Editor("System.Web.UI.Design.UrlEditor", typeof(System.Drawing.Design.UITypeEditor)),
54
DefaultValue(""),
55
]
56
public string SortDescImageUrl
57
{
58
get
59
{
60
object o = ViewState["SortImageDesc"];
61
return (o != null ? o.ToString() : "");
62
}
63
set
64
{
65
ViewState["SortImageDesc"] = value;
66
}
67
}
68
#endregion
69
重写方法#region 重写方法
70
protected override void OnSorting(GridViewSortEventArgs e)
71
{
72
if (AllowMultiColumnSorting)
73
{
74
e.SortExpression = GetSortExpression(e);
75
}
76
77
base.OnSorting(e);
78
}
79
protected override void OnRowCreated(GridViewRowEventArgs e)
80
{
81
if (e.Row.RowType == DataControlRowType.Header)
82
{
83
if (SortExpression != String.Empty)
84
{
85
DisplaySortOrderImages(SortExpression, e.Row);
86
this.CreateRow(0, 0, DataControlRowType.EmptyDataRow, DataControlRowState.Normal);
87
}
88
}
89
base.OnRowCreated(e);
90
}
91
#endregion
92
受保护的方法#region 受保护的方法
93
/**//// <summary>
94
/// 获取排序表达式
95
/// </summary>
96
protected string GetSortExpression(GridViewSortEventArgs e)
97
{
98
string[] sortColumns = null;
99
string sortAttribute = SortExpression;
100
101
if (sortAttribute != String.Empty)
102
{
103
sortColumns = sortAttribute.Split(",".ToCharArray());
104
}
105
if (sortAttribute.IndexOf(e.SortExpression) > 0 || sortAttribute.StartsWith(e.SortExpression))
106
{
107
sortAttribute = ModifySortExpression(sortColumns, e.SortExpression);
108
}
109
else
110
{
111
sortAttribute += String.Concat(",", e.SortExpression, " ASC ");
112
}
113
return sortAttribute.TrimStart(",".ToCharArray()).TrimEnd(",".ToCharArray());
114
115
}
116
/**//// <summary>
117
/// 修改排序顺序
118
/// </summary>
119
protected string ModifySortExpression(string[] sortColumns, string sortExpression)
120
{
121
string ascSortExpression = String.Concat(sortExpression, " ASC ");
122
string descSortExpression = String.Concat(sortExpression, " DESC ");
123
124
for (int i = 0; i < sortColumns.Length; i++)
125
{
126
127
if (ascSortExpression.Equals(sortColumns[i]))
128
{
129
sortColumns[i] = descSortExpression;
130
}
131
132
else if (descSortExpression.Equals(sortColumns[i]))
133
{
134
Array.Clear(sortColumns, i, 1);
135
}
136
}
137
138
return String.Join(",", sortColumns).Replace(",,", ",").TrimStart(",".ToCharArray());
139
140
}
141
/**//// <summary>
142
/// 获取当前的表达式对所选列进行排序
143
/// </summary>
144
protected void SearchSortExpression(string[] sortColumns, string sortColumn, out string sortOrder, out int sortOrderNo)
145
{
146
sortOrder = "";
147
sortOrderNo = -1;
148
for (int i = 0; i < sortColumns.Length; i++)
149
{
150
if (sortColumns[i].StartsWith(sortColumn))
151
{
152
sortOrderNo = i + 1;
153
if (AllowMultiColumnSorting)
154
{
155
sortOrder = sortColumns[i].Substring(sortColumn.Length).Trim();
156
}
157
else
158
{
159
sortOrder = ((SortDirection == SortDirection.Ascending) ? "ASC" : "DESC");
160
}
161
}
162
}
163
}
164
/**//// <summary>
165
/// 绘制升序降序的图片
166
/// </summary>
167
protected void DisplaySortOrderImages(string sortExpression, GridViewRow dgItem)
168
{
169
string[] sortColumns = sortExpression.Split(",".ToCharArray());
170
171
for (int i = 0; i < dgItem.Cells.Count; i++)
172
{
173
if (dgItem.Cells[i].Controls.Count > 0 && dgItem.Cells[i].Controls[0] is LinkButton)
174
{
175
string sortOrder;
176
int sortOrderNo;
177
string column = ((LinkButton)dgItem.Cells[i].Controls[0]).CommandArgument;
178
SearchSortExpression(sortColumns, column, out sortOrder, out sortOrderNo);
179
if (sortOrderNo > 0)
180
{
181
string sortImgLoc = (sortOrder.Equals("ASC") ? SortAscImageUrl : SortDescImageUrl);
182
183
if (sortImgLoc != String.Empty)
184
{
185
Image imgSortDirection = new Image();
186
imgSortDirection.ImageUrl = sortImgLoc;
187
dgItem.Cells[i].Controls.Add(imgSortDirection);
188
189
}
190
else
191
{
192
193
if (AllowMultiColumnSorting)
194
{
195
Literal litSortSeq = new Literal();
196
litSortSeq.Text = sortOrderNo.ToString();
197
dgItem.Cells[i].Controls.Add(litSortSeq);
198
199
}
200
}
201
}
202
}
203
}
204
205
}
206
#endregion
207
}

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

149



150

151



152

153

154



155

156

157

158



159

160

161

162

163

164


165

166

167

168



169

170

171

172



173

174



175

176

177

178

179

180



181

182

183

184



185

186

187

188

189

190

191



192

193

194



195

196

197

198

199

200

201

202

203

204

205

206

207

第二:详尽的分页信息显示,此功能没有封装成控件形式,直接在GridView_DataBound事件中对尾页操作即可。
下面是多列排序与分页显示代码的演示





















































































































效果:
如需要源码者:请加入WinFX团队。