以下内容翻译自Using OnItemDataBound with Repeater in ASP.NET and C#
ASP.NET学习之Repeater
在这个教程学习使用Repeater控件的OnItemDataBound
事件
在这个例子中,在page加载时创建一个datatable(列有Name
、Age
和City
),填充Repeater
。在显示数据时,如果Age
列为空,就显示一个备注,先添加一个Repeater
到页面上:
<form id="form1" runat="server">
<asp:Repeater ID="Repeater1" runat="server">
<HeaderTemplate>
</HeaderTemplate>
<ItemTemplate>
</ItemTemplate>
<FooterTemplate>
</FooterTemplate>
</asp:Repeater>
</form>
向其中添加一些Literal
控件来显示数据:
<form id="form1" runat="server">
<asp:Repeater ID="Repeater1" runat="server">
<HeaderTemplate>
<table><tr><th>Name</th><th>Age</th><th>City</th><th>Notes</th></tr>
</HeaderTemplate>
<ItemTemplate>
<tr>
<td><asp:Literal ID="lit_Name" runat="server" /></td>
<td><asp:Literal ID="lit_Age" runat="server" /></td>
<td><asp:Literal ID="lit_City" runat="server" /></td>
<td><asp:Literal ID="lit_Notes" runat="server" /></td>
</tr>
</ItemTemplate>
<FooterTemplate>
</table>
</FooterTemplate>
</asp:Repeater>
</form>
在Page_Load
中创建一个datatable
,填充它,并把它与repeater
绑定
DataTable dt = new DataTable();
DataColumn dc;
dc = new DataColumn();
dc.ColumnName = "Name";
dt.Columns.Add(dc);
dc = new DataColumn();
dc.ColumnName = "Age";
dt.Columns.Add(dc);
dc = new DataColumn();
dc.ColumnName = "City";
dt.Columns.Add(dc);
DataRow dr;
dr = dt.NewRow();
dr["Name"] = "Fred";
dr["Age"] = "54";
dr["City"] = "Rockingham";
dt.Rows.Add(dr);
dr = dt.NewRow();
dr["Name"] = "Bill";
dr["Age"] = "";
dr["City"] = "Rio";
dt.Rows.Add(dr);
dr = dt.NewRow();
dr["Name"] = "Rhona";
dr["Age"] = "32";
dr["City"] = "LA";
dt.Rows.Add(dr);
Repeater1.DataSource = dt;
Repeater1.DataBind();
这里,在table中添加了3行数据, Name
, Age
, 和City
,注意这里预留第二行的Age
为空,这个例子中,我们会检查Age
列是否为空,为空就给用户显示一个信息。
创建Repeater
的ItemDataBound
事件
protected void Repeater1_OnItemDataBound(object sender, RepeaterItemEventArgs e)
{
RepeaterItem item = e.Item; if (item.ItemType == ListItemType.AlternatingItem || item.ItemType == ListItemType.Item)
{
}
}
在这个方法中,会检查当前的item是否是ListItemType.Item
,或者是ListItemType.AlternatingItem
。这是因为在数据绑定时也会遍历header
和footer
。
然后在Repeater
上添加该事件
<asp:Repeater ID="Repeater1" runat="server" OnItemDataBound="Repeater1_OnItemDataBound">
添加检查Age
值:
protected void Repeater1_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
RepeaterItem item = e.Item;
if (item.ItemType == ListItemType.AlternatingItem || item.ItemType == ListItemType.Item)
{
Literal lit_Age = (Literal)item.FindControl("lit_Age");
if (String.IsNullOrEmpty(lit_Age.Text))
{
Literal lit_Name = (Literal)item.FindControl("lit_Name");
Literal lit_Notes = (Literal)item.FindControl("lit_Notes");
lit_Age.Text = "-";
lit_Notes.Text = lit_Name.Text + "'s age is unknown.";
}
}
}
这里检查Age
值是否为空,为空的话就age显示为"-"
,并提示用户用户的age
未知
最后,添加Literal
控件Text
的值
<td><asp:Literal ID="lit_Name" runat="server" Text='<%# Eval("Name") %>' /></td>
<td><asp:Literal ID="lit_Age" runat="server" Text='<%# Eval("Age") %>' /></td>
<td><asp:Literal ID="lit_City" runat="server" Text='<%# Eval("City") %>' /></td>
<td><asp:Literal ID="lit_Notes" runat="server" /></td>
显示效果:
ItemCommand
ItemCommand :用来响应Item模板中的控件的事件
在官方文档中Repeater.ItemCommand Event中,用来响应repeater中asp:button
的事件
void R1_ItemCommand(Object Sender, RepeaterCommandEventArgs e) {
Label2.Text = "The " + ((Button)e.CommandSource).Text + " button has just been clicked; <br />";
}
也可以参考 Repeater数据控件的两个重要事件ItemDataBound 和 ItemCommand
//响应Item模板中控件的事件---------点击按钮,库存+1
protected void Repeater1_ItemCommand(object source, RepeaterCommandEventArgs e)
{
if (e.CommandName == "addButton")//判断这个Item里哪个控件响应的这个事件
{
string part_code = (string)e.CommandArgument;//获取Item传过来的参数
//下面是通过Linq修改数据(即:使库存+1)
DataClasses1DataContext dc = new DataClasses1DataContext();
var rs = dc.tbl_stock_dtl.Select(r => r).Where(r => r.part_code == part_code);
if (rs.Count() > 0)
{
foreach (tbl_stock_dtl t in rs)
{
t.stock_num += 1;
}
}
dc.SubmitChanges();
Repeater1.DataBind();//强行刷新数据,就是说,库存+1后,立马显示新的数据。
}
}
补充
1.<%# “whatever” %>
的含义
参考What does <%# “whatever” %> mean in ASP.NET?duplicate
<%# … %>
Data-binding expressions are an important set of code delimiters, which are used to create a binding between a server control property and a data source.
2.其它的Template
a.<AlternatingItemTemplate></AlternatingItemTemplate>
用于定义交替项呈现的内容和布局。所谓的交替项方式,就是在Repeater
控件和DataList
控件中允许奇偶项以不同的内容和布局形式显示数据,其中奇数行由AlternatingItemTemplate
模板定义(索引号从1开始),偶数行由ItemTemplate
模板定义(引号从0开始)。
b.<SeparatorTemplate></SeparatorTemplate>
相当于分隔符
3.如何理解Eval
方法
参考官方文档DataBinder.Eval 方法 (Object, String)
<asp:Repeater ID="ProductList" runat="server">
<ItemTemplate>
<%# DataBinder.Eval(Container.DataItem, "Name") %> for only <%# DataBinder.Eval(Container.DataItem, "Price", "{0:c}") %>
<br />
<a href='<%# DataBinder.Eval(Container.DataItem, "ProductID", "details.asp?id={0}") %>'>See Details</a>
<br />
<br />
</ItemTemplate>
</asp:Repeater>
也可以直接使用Eval
<asp:Repeater ID="ProductList" runat="server">
<ItemTemplate>
<%# Eval("Name") %> for only <%# Eval("Price", "{0:c}") %>
<br />
<a href='<%# Eval("ProductID", "details.asp?id={0}") %>'>See Details</a>
<br />
<br />
</ItemTemplate>
</asp:Repeater>
Eval
方法格式化时间
<%#Eval("PublishTime", "{0:yyyy-MM-dd}") %>
4.获取ItemDataBound事件中数据源的某一个域
参考:
- How to access datasource fields in an ASP.NET Repeaters ItemDataBound event?
- Repeater.ItemDataBound Event
如果DataSource
是DataTable
,则DataItem
包含一个DataRowView
protected void rptMyReteater_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
Button b = e.Item.FindControl("myButton") as Button;
DataRowView drv = e.Item.DataItem as DataRowView;
b.CommandArgument = drv.Row["ID_COLUMN_NAME"].ToString();
}
}
如果是某个类型对象的话,可以使用如下的形式:
if (((Evaluation)e.Item.DataItem).Rating == "Good")
{
((Label)e.Item.FindControl("RatingLabel")).Text= "<b>***Good***</b>";
}
5.遍历repeater的items找到对应id的控件
foreach (RepeaterItem ri in Repeater1.Items)
{
if (ri.ItemType == ListItemType.Item || ri.ItemType == ListItemType.AlternatingItem)
{
CheckBox checkBoxInRepeater = ri.FindControl("CheckBox1") as CheckBox;
//do something with the checkbox
}
}
6.获取repeater中的索引号
<%#Container.ItemIndex %>