很久都没有写一点东西了,最近一直在学习.net,前两天看到椰子林写的一篇《ASP.NET分页组件学与用》,于是自己就跟着做了一遍,一次成功,在此向他表示感谢,也向他那种共享的精神致敬!可是后来我发觉这个组件用起来有点麻烦,在Page_Load里面不但要得到记录集,还要写SQL语句分页,最后还要自己写代码将包含数据的
1<table></table>
输出到客户端,于是我就想呀要是可以像DataGrid那样只是简单的绑定一下就可以用就好,分页,显示数据呀这些都交给组件去完成,正是这灵光一现,我就开始冲动了,没办法程序就是有这么大的魅力!结果,我昨天晚上失眠了,哎!冲动的惩罚呀!今天早上,我带着红肿的眼睛走进了机房,开始实现我昨天晚上梦见的那个东东,幸运的是--我实现了,呵呵,一个字爽!忘了告诉大家,我还是一个学生,做出来我很高兴了,技巧谈不上,高手们看了莫怪。下面我把基本的做法说一下!
如何做自定义控件,以及如何实现分页在这里我就不多说了,大家可以看一下椰子林写的相关文章,我要说说我的做法:
首先定义一个DataSource属性,如下:
private DataTable dt; //数据源
///
1<summary>
2/// 数据源
3/// </summary>
public DataTable DataSource
{
get
{
return dt;
}
set
{
if ( value == null )
throw new Exception("数据源不可为空");
else
dt = value ;
}
}
该属性用于接受前端传进来的DataTable对象。我们可以在前端使用ADO.NET获得数据并将数据填充到一个DataTable中,再将此包含数据的DataTable赋于组件的DataSource属性,接下来的工作就是由组件向客户端输出包含数据的
1<table></table>
标签了,怎么样简单吧!其实没有做多少改进,只是简单的扩展了一下,如下:
///
1<summary>
2/// 创建数据表
3/// </summary>
///
1<returns> 表格的Html表示字符串 </returns>
protected string CreateDataTable()
{
string table = null; //表格,显示了所有的字段和记录
string tableHead = null ; // 表头用于显示字段名的
1<tr>
2string tdHead = null ; // 表头用于显示字段名的<td>包含在 tableHead中
3string tableBody = null ; // 表主体用于显示记录的<tr>
4
5// 为了实现分页定义min和max两个变量
6// min代表从那一条记录开始显示
7// max代表到那一条记录结束
8// 如果当前是第2页每页显示10条记录的话,那么min的值就是10,max的值就是20
9int min = 0;
10int max = 0;
11
12// for循环用于产生表头,即字段名
13for ( int i = 0; i < this .dt.Columns.Count; i++)
14{
15tdHead = tdHead + "<td>" + this .dt.Columns[i].ColumnName + "</td>";
16}
17
18// 判断当前页是否最后一页
19if ( this .currentpage == this .PageCount)
20{
21min = (this.currentpage - 1) * this .count;
22max = this .dt.Rows.Count;
23}
24else
25{
26min = ( this .currentpage - 1) * this .count;
27max = this .currentpage * this .count;
28}
29
30// for循环用于产生表主体,即提取记录
31for ( int j = min; j < max; j++)
32{
33tableBody = tableBody + "<tr bgcolor="#FFFFFF">";
34
35for ( int k = 0; k < this.dt.Columns.Count; k++)
36{
37tableBody = tableBody + "<td>" + this .dt.Rows[j][k].ToString() + "</td>";
38}
39
40tableBody = tableBody + "</tr>";
41}
42
43tableHead = "<tr bgcolor="#FFFFFF">" + tdHead + "</tr>";
44
45table = "<table bgcolor="#000000" border="0" cellpadding="0" cellspacing="1" height="100%" style="font-size:9pt" width="100%">" + tableHead + tableBody + "</table>";
46
47return table;
48}
49
50这样就得到了包含数据的表格的Html字符串,跟着就是做分页部分,最后重写Render(HtmlTextWriter output)方法将整个组件输出到客户端!这里我不一一详述步骤,我把代码帖出来,有兴趣的可以将代码拷贝到本机上运行一下!
51
52组件源代码如下:(调试通过)
53
54public class MyDataGrid : System.Web.UI.WebControls.WebControl
55{
56private int currentpage; //当前页
57private int count; //每页显示的记录条数
58private int navigcount; //导航连接的个数
59private DataTable dt; //数据源
60
61private const string SCRIPTSTRING = "<script language="javascript">\n" +
62" function go(ctrl,max)\n" +
63"{\n" +
64"if(ctrl.value >= 1 && ctrl.value <= max)\n" +
65"{\n" +
66"var url;\n" +
67"var index;\n" +
68"url = location.href;\n" +
69"index = url.indexOf('?');\n" +
70"if(index == -1)\n" +
71"{\n" +
72"}\n" +
73"else\n" +
74"{\n" +
75"url = url.substring(0,index);\n" +
76"}\n" +
77"location.href = url + '?CurrentPage=' + ctrl.value;\n" +
78"}\n" +
79"else\n" +
80"{\n" +
81"alert('您输入的页码必须是符合页面要求的数字,最大值是:' + max);\n" +
82"return false;\n" +
83"}\n" +
84"}\n" +
85"</script>\n";
86
87/// <summary>
88/// 当前页
89/// </summary>
90public int CurrentPage
91{
92get
93{
94return currentpage;
95}
96set
97{
98if ( value <= 0)
99currentpage = 1;
100else
101currentpage = value ;
102}
103}
104
105/// <summary>
106/// 每页显示的记录条数
107/// </summary>
108public int Count
109{
110get
111{
112return count;
113}
114set
115{
116if ( value <= 0)
117count = 10;
118else
119count = value ;
120}
121}
122
123/// <summary>
124/// 导航连接的个数
125/// </summary>
126public int NavigCount
127{
128get
129{
130return navigcount;
131}
132set
133{
134if ( value <= 0)
135navigcount = 10;
136else
137navigcount = value ;
138}
139}
140
141/// <summary>
142/// 总页数
143/// </summary>
144public int PageCount
145{
146get
147{
148if ( this .dt.Rows.Count % count > 0)
149return (( int ) this .dt.Rows.Count / count) + 1;
150else
151return (( int ) this .dt.Rows.Count / count);
152}
153}
154
155/// <summary>
156/// 数据源
157/// </summary>
158public DataTable DataSource
159{
160get
161{
162return dt;
163}
164set
165{
166if ( value == null )
167throw new Exception("数据源不可为空");
168else
169dt = value;
170}
171}
172
173protected override void Render(HtmlTextWriter output)
174{
175string Table = CreateDataTable();
176string PageControl = CreatePageControl();
177
178string Result = string .Format("<table bgcolor="#000000" border="0" cellpadding="0" cellspacing="1" height="93" style="font-size: 9pt" width="724">\n" +
179"<tr bgcolor="#FFFFFF">\n" + "<td height="68" valign="top" width="724">{0}</td>\n" + "</tr>\n" +
180"<tr bgcolor="#FFFFFF">\n" + "<td height="25" valign="top" width="724">{1}</td>\n" + "</tr>\n" + "</table>\n",Table.ToString(),PageControl.ToString());
181
182output.Write(Result.ToString());
183}
184
185/// <summary>
186/// 创建数据表
187/// </summary>
188/// <returns> 表格的Html表示字符串 </returns>
189protected string CreateDataTable()
190{
191string table = null; //表格,显示了所有的字段和记录
192string tableHead = null ; // 表头用于显示字段名的<tr>
193string tdHead = null ; // 表头用于显示字段名的<td>包含在 tableHead中
194string tableBody = null ; // 表主体用于显示记录的<tr>
195
196// 为了实现分页定义min和max两个变量
197// min代表从那一条记录开始显示
198// max代表到那一条记录结束
199// 如果当前是第2页每页显示10条记录的话,那么min的值就是10,max的值就是20
200int min = 0;
201int max = 0;
202
203// for循环用于产生表头,即字段名
204for ( int i = 0; i < this .dt.Columns.Count; i++)
205{
206tdHead = tdHead + "<td>" + this .dt.Columns[i].ColumnName + "</td>";
207}
208
209// 判断当前页是否最后一页
210if ( this .currentpage == this .PageCount)
211{
212min = (this.currentpage - 1) * this .count;
213max = this .dt.Rows.Count;
214}
215else
216{
217min = ( this .currentpage - 1) * this .count;
218max = this .currentpage * this .count;
219}
220
221// for循环用于产生表主体,即提取记录
222for ( int j = min; j < max; j++)
223{
224tableBody = tableBody + "<tr bgcolor="#FFFFFF">";
225
226for ( int k = 0; k < this.dt.Columns.Count; k++)
227{
228tableBody = tableBody + "<td>" + this .dt.Rows[j][k].ToString() + "</td>";
229}
230
231tableBody = tableBody + "</tr>";
232}
233
234tableHead = "<tr bgcolor="#FFFFFF">" + tdHead + "</tr>";
235
236table = "<table bgcolor="#000000" border="0" cellpadding="0" cellspacing="1" height="100%" style="font-size:9pt" width="100%">" + tableHead + tableBody + "</table>";
237
238return table;
239}
240
241
242/// <summary>
243/// 创建分页控件
244/// </summary>
245/// <returns> 返回分页控件的Html表示字符串 </returns>
246protected string CreatePageControl()
247{
248string leftInfo = string .Format("页:{0}/{1}"+" "+"每页{2}条"+" "+"共{3}条",
249this .CurrentPage.ToString(), this .PageCount.ToString(), this .Count.ToString(), this .dt.Rows.Count.ToString());
250
251int min = 0;
252int max = 0;
253
254if ( this .CurrentPage > this .PageCount)
255{
256this .CurrentPage = this . PageCount;
257}
258
259if ( this .CurrentPage % this .Count == 0)
260{
261min = this .CurrentPage + 1;
262max = this .CurrentPage + this .Count;
263}
264else if ( this .CurrentPage % this .Count == 1&& this .CurrentPage > this .Count)
265{
266min = ((( int ) this .CurrentPage / this .Count) - 1) * this .Count + 1;
267max = this .CurrentPage - 1;
268}
269else
270{
271min = (( int ) this .CurrentPage / this .Count) * this .Count + 1;
272max = ((( int ) this .CurrentPage / this .Count) + 1) * this .Count;
273}
274
275string numberStr = " ";
276string url = this .Context.Request.Url.ToString();
277
278if (url.IndexOf("?") == -1)
279{
280}
281else
282{
283url = url.Substring(0,url.IndexOf("?"));
284}
285
286for ( int i = min; i <= max; i++)
287{
288if (i <= this .PageCount)
289{
290if (i == this .CurrentPage)
291{
292numberStr = numberStr + "<a ?currentpage=" + i.ToString() + " href=" + url + ">" + "<i style="color:red">" + i.ToString() + "</i>" +"</a>" + "\n";
293}
294else
295{
296numberStr = numberStr + "<a ?currentpage=" + i.ToString() + " href=" + url + ">" + i.ToString() +"</a>" + "\n";
297}
298}
299}
300
301string first,prev,next,last;
302first = url + "?CurrentPage=" + 1;
303
304if ( this .CurrentPage == 1)
305{
306prev = url + "?CurrentPage=1";
307}
308else
309{
310prev = url + "?CurrentPage=" + (this.CurrentPage - 1).ToString();
311}
312
313if ( this .CurrentPage == this .PageCount)
314{
315next = url + "?CurrentPage="+ this .PageCount;
316}
317else
318{
319next = url + "?CurrentPage=" + ( this .CurrentPage + 1).ToString();
320}
321
322last = url + "?CurrentPage=" + this .PageCount;
323
324string centerInfo = string .Format("<font face="Webdings" style="font-size:14px"><a href="{0}">7</a><a href="{1}">3</a></font>{2}<font face="Webdings" style="font-size:14px"><a href="{3}">4</a><a href="{4}">8</a></font>",first,prev,numberStr,next,last);
325
326string result = string .Format("<table border="0" cellpadding="0" cellspacing="0" style="font-size:9pt" width="100%">\n" +
327"<tr><td align="left" width="25%">{0}</td>\n" +
328"<td align="right" width="61%">{1}</td>" +
329"<td align="right" width="14%"><input name="T1" size="4" style="border-bottom:solid 1pt gray;border-top :solid 1pt gray; border-left:solid 1pt gray;border-right:solid 1pt gray;" type="text"/> \n <input name="B1" onclick="go(T1,{2})" size="6" style="border-bottom:solid 1pt gray;border-top :solid 1pt gray; border-left:solid 1pt gray;border-right:solid 1pt gray;" type="button" value="go"/></td>\n" +
330"</tr></table>",leftInfo,centerInfo, this .PageCount);
331
332return result;
333}
334
335protected override void OnPreRender(EventArgs e)
336{
337base .OnPreRender (e);
338if (!Page.IsClientScriptBlockRegistered("WEREW-332DFAF-FDAFDSFDSAFD"))
339{
340Page.RegisterClientScriptBlock("WEREW-332DFAF-FDAFDSFDSAFD",SCRIPTSTRING);
341}
342}
343}
344
345测试工程代码:
346
347public class TestMyDataGrid : System.Web.UI.Page
348{
349protected myControlLibrary.MyDataGrid MyDataGrid1;
350
351private void Page_Load(object sender, System.EventArgs e)
352{
353// 在此处放置用户代码以初始化页面
354int currentpage;
355if (this.Request.Params["CurrentPage"] == null)
356{
357currentpage = 1;
358}
359else
360{
361currentpage = Convert.ToInt32(this.Request.Params["CurrentPage"].ToString());
362}
363
364this .MyDataGrid1.CurrentPage = currentpage;
365this .MyDataGrid1.Count = 10;
366this .MyDataGrid1.NavigCount = 10;
367
368SqlConnection conn = new SqlConnection("server=localhost; database=NorthWind; uid=sa");
369SqlCommand cmd = new SqlCommand("select * from [Order Details]",conn);
370SqlDataAdapter da = new SqlDataAdapter();
371da.SelectCommand = cmd;
372DataSet ds = new DataSet();
373
374conn.Open();
375da.Fill(ds,"table");
376conn.Close();
377
378this .MyDataGrid1.DataSource = ds.Tables["table"];
379}
380
381#region Web Form Designer generated code
382override protected void OnInit(EventArgs e)
383{
384//
385// CODEGEN:该调用是 ASP.NET Web 窗体设计器所必需的。
386//
387InitializeComponent();
388base .OnInit(e);
389}
390
391/// <summary>
392/// 设计器支持所需的方法 - 不要使用代码编辑器修改
393/// 此方法的内容。
394/// </summary>
395private void InitializeComponent()
396{
397this .Load += new System.EventHandler(this.Page_Load);
398
399}
400#endregion
401}
402
403
404页面版排的不好,只好劳动一下你,呵呵!</tr></td></tr></tr></td></tr>