一、绑定控件之Repeater
.NET封装了多种数据绑定控件,诸如GridView、DataList等但该篇文章将会从Repeater入手,因为Repeater只提供了基本的数据绑定模板,没有内置其它分页等功能,所以它是最原始的数据绑定控件,只要能够熟练运用Repeater控件其它的绑定控件也就很简单了。
1、Repeater简介
Repeater 控件是基本模板化数据列表。 它不像GridView控件一样能够可视化的设计格式或样式,因此开发时在控件模板中必须显式声明所有格式、格式和样式标记。另外Repeater控件没有内置选择、排序、编辑、分页等功能,它只提供了基本的数据绑定,但是它为开发人员提供了ItemCommand 事件,该事件支持在控件中收发命令。
想要绑定数据,模板是必不可少的,Repeater控件同样支持数据模板,而且还可以在模板中添加想要的标签,它主要用法如下图:
Note:每个 Repeater 控件必须定义 ItemTemplate。
二、控件使用技巧
上文讲解了Repeater基本的使用方法及它的一些基本特性,接下来做几个经典的示例来运用Repeater控件。
1、数据绑定之删除、编辑
该示例将会使用Asp.net的前台和后台结合来实现显示数据,并能够编辑和删除数据。
删除页面:
编辑页面:
前台代码:在单击编辑按钮后将会进入编辑页面,页面是由两个Panel控件来控制,通过传递ID号的方式判断显示的是编辑页面还是删除页面,另外前台代码通过设置控件的CommandArgument属性来传递后台所需要判断的id号。
1
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
|
< body > < form id = "form1" runat = "server" > < div > < asp:Repeater ID = "userRepeat" runat = "server" OnItemCommand = "userRepeat_ItemCommand" OnItemDataBound = "userRepeat_ItemDataBound" > < HeaderTemplate > < table border = "1" style = "width:1000px;text-align:center;border-collapse:collapse;" > < thead style = "background-color:red;" > < tr > < th >ID</ th > < th >内容</ th > < th >操作</ th > </ tr > </ thead > </ HeaderTemplate > < ItemTemplate > < asp:Panel ID = "plItem" runat = "server" > < tr > < td >< asp:Label runat = "server" ID = "lblID" Text='<%#Eval("id") %>'></ asp:Label ></ td > < td ><%#Eval("name") %></ td > < td > < asp:LinkButton ID = "lbtEdit" CommandName = "Edit" CommandArgument='<%#Eval("id") %>' runat="server">编辑</ asp:LinkButton > < asp:LinkButton ID = "lbtDelete" CommandName = "Delete" CommandArgument='<%#Eval("id") %>' runat="server">删除</ asp:LinkButton > </ td > </ tr > </ asp:Panel > < asp:Panel ID = "plEdit" runat = "server" > < tr > < td >< asp:Label runat = "server" ID = "Label1" Text='<%#Eval("id") %>'></ asp:Label ></ td > < td >< asp:TextBox ID = "txtName" runat = "server" Text='<%#Eval("name") %>'></ asp:TextBox ></ td > < td > < asp:LinkButton ID = "lbtCancel" CommandName = "Cancel" CommandArgument='<%#Eval("id") %>' runat="server">取消</ asp:LinkButton > < asp:LinkButton ID = "lbtUpdate" CommandName = "Update" CommandArgument='<%#Eval("id") %>' runat="server">更新</ asp:LinkButton > </ td > </ tr > </ asp:Panel > </ ItemTemplate > < FooterTemplate > </ table > </ FooterTemplate > </ asp:Repeater > </ div > </ form > </ body > |
后台代码:在后台代码中很重要的两个事件是ItemCommand和ItemDataBound,其中ItemCommand负责接收前台传进来的按钮命令,根据命令的参数来设置后台传递的id,并在ItemDataBound中来验证id判断切换显示Panel。
1
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
|
using System; using System.Collections.Generic; using System.Data; using System.Data.SqlClient; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; namespace WebApplication4 { public partial class EditPage : System.Web.UI.Page { private int id = 0; //保存指定行操作所在的ID号 /// <summary> /// 窗体加载时绑定数据 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> protected void Page_Load( object sender, EventArgs e) { if (!Page.IsPostBack) { this .DataBindToRepeater(); //将数据绑定到Repeater控件上 } } /// <summary> /// 将数据源绑定Repeater控件上 /// </summary> private void DataBindToRepeater() { //使用using语句进行数据库连接 using (SqlConnection sqlCon= new SqlConnection( "server=.;database=MyBlog;uid=sa;pwd=1" )) { sqlCon.Open(); //打开数据库连接 SqlCommand sqlcom = new SqlCommand(); //创建数据库命令对象 sqlcom.CommandText = "select * from match" ; //为命令对象指定执行语句 sqlcom.Connection = sqlCon; //为命令对象指定连接对象 this .userRepeat.DataSource = sqlcom.ExecuteReader(); //为Repeater对象指定数据源 this .userRepeat.DataBind(); //绑定数据源 } } /// <summary> /// Repeater控件命令事件 /// </summary> /// <param name="source"></param> /// <param name="e"></param> protected void userRepeat_ItemCommand( object source, RepeaterCommandEventArgs e) { //获取命令文本,判断发出的命令为何种类型,根据命令类型调用事件 if (e.CommandName== "Edit" ) //编辑命令 { id = int .Parse(e.CommandArgument.ToString()); //获取命令ID号 } else if (e.CommandName== "Cancel" ) //取消更新命令 { id = -1; } else if (e.CommandName== "Delete" ) //删除行内容命令 { id = int .Parse(e.CommandArgument.ToString()); //获取删除行的ID号 //删除选定的行,并重新指定绑定操作 this .DeleteRepeater(id); } else if (e.CommandName == "Update" ) //更新行内容命令 { //获取更新行的内容和ID号 string strText = ((TextBox)e.Item.FindControl( "txtName" )).Text.Trim(); int intId= int .Parse(((Label)e.Item.FindControl( "lblID" )).Text); //更新Repeater控件的内容 this .UpdateRepeater(strText,intId); } //重新绑定控件上的内容 this .DataBindToRepeater(); } /// <summary> /// 删除行内容 /// </summary> /// <param name="intId">删除行所在内容的ID</param> private void DeleteRepeater( int intId) { using (SqlConnection sqlCon = new SqlConnection( "server=.;database=MyBlog;uid=sa;pwd=1" )) { sqlCon.Open(); //打开数据库连接 SqlCommand sqlcom = new SqlCommand(); //创建数据库命令对象 sqlcom.CommandText = "delete from match where id=@id" ; //为命令对象指定执行语句 sqlcom.Connection = sqlCon; //为命令对象指定连接对象 //创建参数集合,并向sqlcom中添加参数集合 SqlParameter sqlParam = new SqlParameter( "@id" , intId); sqlcom.Parameters.Add(sqlParam); sqlcom.ExecuteNonQuery(); //指定更新语句 } } /// <summary> /// 更新Repeater控件中的内容 /// </summary> /// <param name="strText">修改后的内容</param> /// <param name="intId">内容所在行的ID号</param> private void UpdateRepeater( string strText, int intId) { using (SqlConnection sqlCon = new SqlConnection( "server=.;database=MyBlog;uid=sa;pwd=1" )) { sqlCon.Open(); //打开数据库连接 SqlCommand sqlcom = new SqlCommand(); //创建数据库命令对象 sqlcom.CommandText = "update match set name=@str where id=@id" ; //为命令对象指定执行语句 sqlcom.Connection = sqlCon; //为命令对象指定连接对象 //创建参数集合,并向sqlcom中添加参数集合 SqlParameter[] sqlParam = { new SqlParameter( "@str" , strText), new SqlParameter( "@id" , intId) }; sqlcom.Parameters.AddRange(sqlParam); sqlcom.ExecuteNonQuery(); //指定更新语句 } } /// <summary> /// Repeater控件数据绑定时发生的事件 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> protected void userRepeat_ItemDataBound( object sender, RepeaterItemEventArgs e) { //判断Repeater控件中的数据是否是绑定的数据源,如果是的话将会验证是否进行了编辑操作 //ListItemType 枚举表示在一个列表控件可以包括,例如 DataGrid、 DataList和 Repeater 控件的不同项目。 if (e.Item.ItemType==ListItemType.Item || e.Item.ItemType==ListItemType.AlternatingItem) { //获取绑定的数据源,这里要注意上面使用sqlReader的方法来绑定数据源,所以下面使用的DbDataRecord方法获取的 //如果绑定数据源是DataTable类型的使用下面的语句就会报错. System.Data.Common.DbDataRecord record = (System.Data.Common.DbDataRecord)e.Item.DataItem; //DataTable类型的数据源验证方式 //System.Data.DataRowView record = (DataRowView)e.Item.DataItem; //判断数据源的id是否等于现在的id,如果相等的话证明现点击了编辑触发了userRepeat_ItemCommand事件 if (id == int .Parse(record[ "id" ].ToString())) { ((Panel)e.Item.FindControl( "plItem" )).Visible = false ; ((Panel)e.Item.FindControl( "plEdit" )).Visible = true ; } else { ((Panel)e.Item.FindControl( "plItem" )).Visible = true ; ((Panel)e.Item.FindControl( "plEdit" )).Visible = false ; } } } } } |
2、分页--PageDataSource
前台代码:使用原始的html文本,并添加了一个Literal标签,用来动态添加并指定html标签。
页面截图:
1
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
|
< html xmlns = "http://www.w3.org/1999/xhtml" > < head runat = "server" > < meta http-equiv = "Content-Type" content = "text/html; charset=utf-8" /> < title ></ title > < style type = "text/css" > .pageBar { margin-top: 10px; } .pageBar a { color: #333; font-size: 12px; margin-right: 10px; padding: 4px; border: 1px solid #ccc; text-decoration: none; } </ style > </ head > < body > < form id = "form1" runat = "server" > < div > < asp:Repeater ID = "Repeater1" runat = "server" > < HeaderTemplate > < table border = "1" cellpadding = "0" cellspacing = "0" style = "width:1006px;border-collapse:collapse; text-align:center;" > < tr > < th style = "background-color:red" >ID</ th > < th style = "background-color:red" >内容</ th > </ tr > </ HeaderTemplate > < ItemTemplate > < tr > < td >< asp:Label ID = "lblId" runat = "server" Text='<%# DataBinder.Eval(Container.DataItem,"id") %>' ></ asp:Label ></ td > < td ><%# DataBinder.Eval(Container.DataItem,"name") %></ td > </ tr > </ ItemTemplate > < FooterTemplate > </ table > </ FooterTemplate > </ asp:Repeater > </ div > < div class = "pageBar" > < asp:Literal ID = "ltlPageBar" runat = "server" ></ asp:Literal > </ div > </ form > </ body > </ html > |
后台代码:Repeater控件的数据源是PagedDataSource对象,在页面加载时为该对象动态指定了分页的属性,并使用Literal标签来动态指定每个标签跳转页的链接。
1
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
|
using System; using System.Collections.Generic; using System.Data; using System.Data.SqlClient; using System.Text; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; namespace WebApplication4 { public partial class PageDemo : System.Web.UI.Page { private string id = "" ; protected void Page_Load( object sender, EventArgs e) { if (!Page.IsPostBack) { //设置当前页的索引 int pageIndex = 1; try { //获取当前索要跳转页的索引号 pageIndex = Convert.ToInt32(Request.QueryString[ "Page" ]); //如果是第0页将会跳转入第1页 if (pageIndex <= 0) { pageIndex = 1; } } catch { pageIndex = 1; } DataTable dt = this .GetDataTable(); //获取绑定的数据表 PagedDataSource pds = new PagedDataSource(); //创建分页数据源对象 pds.DataSource = dt.DefaultView; //为数据源对象设置数据源 pds.AllowPaging = true ; //对象允许分页 pds.PageSize = 2; //设置对象每页显示的大小 pds.CurrentPageIndex = pageIndex - 1; //设置数据源的当前页 //向Repeater控件上绑定分页数据源控件 this .Repeater1.DataSource = pds; this .Repeater1.DataBind(); //使用Literal标签来动态指定每个标签跳转页的链接 ltlPageBar.Text = this .GetPageBar(pds); } } /// <summary> /// 获取每个标签上的跳转页的链接地址 /// </summary> /// <param name="pds">分页数据源对象</param> /// <returns>分页操作按钮的html文本</returns> private string GetPageBar(PagedDataSource pds) { string pageBar = string .Empty; //声明页面标签文本 int currentPageIndex = pds.CurrentPageIndex + 1; //获取当前页索引 //判断首页的链接页面 if (currentPageIndex == 1) //如果该页为第一页,则证明它为首页 { pageBar += "<a href=\"javascript:void(0)\">首页</a>" ; } else { //如果不是首页,首页链接的地址将会为1 pageBar += "<a href=\"" + Request.CurrentExecutionFilePath + "?Page=1\">首页</a>" ; } //判断上一页链接的地址 if ((currentPageIndex - 1) < 1) //如果上一页小于1则链接到第一页 { pageBar += "<a href=\"javascript:void(0)\">上一页</a>" ; } else { //如果上一页地址不是1将会链接到上一页 pageBar += "<a href=\"" + Request.CurrentExecutionFilePath + "?Page=" + (currentPageIndex - 1) + "\">上一页</a>" ; } //指定下一页的链接地址 if ((currentPageIndex + 1) > pds.PageCount) { //如果下一页的地址大于总页数,将会连接到首页 pageBar += "<a href=\"javascript:void(0)\">下一页</a>" ; } else { //否则的话链接到下一页 pageBar += "<a href=\"" + Request.CurrentExecutionFilePath + "?Page=" + (currentPageIndex + 1) + "\">下一页</a>" ; } //指定末页的链接地址 if (currentPageIndex == pds.PageCount) { pageBar += "<a href=\"javascript:void(0)\">末页</a>" ; } else { pageBar += "<a href=\"" + Request.CurrentExecutionFilePath + "?Page=" + pds.PageCount + "\">末页</a>" ; } return pageBar; //返回html文本 } /// <summary> /// 获取数据源,重新链接数据 /// </summary> /// <returns>DataTable,数据源</returns> private DataTable GetDataTable() { DataTable dt = new DataTable(); //创建数据库表 using (SqlConnection con = new SqlConnection( "server=.;DataBase=MyBlog;uid=sa;pwd=1;" )) { con.Open(); //打开数据库链接 SqlCommand sqlCom = new SqlCommand(); //声明并创建数据库命令集 StringBuilder sqlStr = new StringBuilder(); //声明sql语句 sqlStr.Append( "select * from match" ); //获取sql语句 sqlCom.CommandText = sqlStr.ToString(); //为sqlcommand对象指定sql语句 sqlCom.Connection = con; //为sqlcommand对象指定链接对象 SqlDataAdapter sqlDa = new SqlDataAdapter(sqlCom); //声明数据库适配器 SqlCommandBuilder sqlBuilder = new SqlCommandBuilder(sqlDa); sqlDa.Fill(dt); //填充表 } return dt; } } } |
结语
文章主要介绍了Repeater控件的基本使用方法,并通过两个示例来更深一步的学习了Repeater控件的使用。虽然Repeater控件封装的操作较少,但它是最基础的数据绑定控件,另外可以通过使用其它控件来弥补Repeater控件的不足,如可以通过使用PagedataSource类来实现数据的分页。文章写到这里并没有结束,下篇文章将会着重讨论ListView。