嵌套Repeater的数据绑定方法之一
使用嵌套的 Repeater 绑定数量可变的 DataTable 对象。
引言
本文是一个小型演示项目,它使用嵌套的 Repeater
来显示具有相同模式的变量数量的 DataTable
对象。
使用代码
在继续之前,我意识到以下解决方案并非最优雅的,但它有效,欢迎批评。
我们有两个 Repeater
控件。内部 Repeater
控件放置在用户控件中,而外部 Repeater
包含在 APSX 页面中,其 <ItemTemplate>
是用户控件。
在深入研究控件的细节之前,首先让我们介绍 App_Code 文件夹中的小型 customDataItem.cs 类。出于某种原因,当我绑定一个 DataSet
时,Repeater
无法按预期渲染所有表,而是多次重复集合中的最后一个 DataTable
。因此,另一种方法是将每个 DataTable
对象封装在一个新的对象中。因此,我创建了一个名为 CustomDataItem
的类。
public class CustomDataItem
{
private DataTable _Data;
public DataTable Data { get { return _Data; } set { _Data = value; } }
public CustomDataItem(DataTable data)
{
_Data = data;
}
}
如您所见,这是一个非常简单的类,它封装了作为参数传递给构造函数的 DataTable
对象。基本上就是这样。
接下来,我们有包含内部 Repeater
的用户控件(.ascx)代码。它非常简单且不言自明。您会注意到我有一个 Literal
控件作为标题。Literal
文本将在数据绑定时设置为表名。
<h2><span><asp:Literal runat="server" ID="ltrTableName"/></span></h2>
<asp:Repeater ID="innerRep" runat="server">
<HeaderTemplate>
<table cellpadding="2" cellspacing="5" border="true">
<thead>
<tr>
<th><b>Name</b></th>
<th><b>Address</b></th>
<th><b>PostCode</b></th>
</tr>
</thead>
</HeaderTemplate>
<ItemTemplate>
<tr>
<td><%# DataBinder.Eval(Container.DataItem,"Name") %></td>
<td><%# DataBinder.Eval(Container.DataItem,"Address") %></td>
<td><%# DataBinder.Eval(Container.DataItem,"PostCode") %></td>
</tr>
</ItemTemplate>
<FooterTemplate>
</table>
</FooterTemplate>
</asp:Repeater>
现在,是用户控件的代码隐藏文件
public partial class InnerRepeaterUserControl : System.Web.UI.UserControl
{
private CustomDataItem _DataItem;
public CustomDataItem DataItem { get { return _DataItem; }
set { _DataItem = value; } }
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
BindData();
}
protected override void OnPreRender(EventArgs e)
{
base.OnPreRender(e);
}
private void BindData()
{
try
{
binnerRep.DataSource = _DataItem.Data;
innerRep.DataBind();
ltrTableName.Text = _DataItem.Data.TableName;
}
catch { }
}
BindData()
方法将 CustomDataItem
对象中包含的 DataTable
和 Literal
文本绑定到表名。CustomDataItem
在主 ASPX 页面上触发的 innerRepeater_DataBound()
事件中传递。稍后我们将详细介绍。
网页上的 ASPX 代码很简单。在这里,我们所做的一切就是注册用户控件并添加外部 Repeater
,以及设置对外部 Repeater
的 ItemDataBound
方法的引用。
<%@ Page Language="C#" AutoEventWireup="true"
CodeFile="Default.aspx.cs" Inherits="_Default" %>
<%@ Register Src="~/InnerRepeaterUserControl.ascx"
TagPrefix="uc" TagName="InnerRep" %>
<!DOCTYPE html PUBLIC
"-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Repeater Demo</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:Repeater runat="server" ID="outerRepeater"
onItemDataBound="outerRepeater_ItemDataBound">
<ItemTemplate>
<uc:InnerRep runat="server" ID="tblInnerRep" />
</ItemTemplate>
</asp:Repeater>
</div>
</form>
</body>
</html>
网页的代码隐藏文件 C# 中完成了大部分工作。在此示例中,我在 createDataTables()
代码中创建了三个简单的 DataTable,并将它们添加到 CustomDataItem
对象的泛型列表中。
BindData()
只是调用该方法并将列表绑定到外部 Repeater
。
最后,在 outerRepeater_ItemDataBound
中,我们找到内部 Repeater
控件,将外部 Repeater
的 e.DataItem
转换为 CustomDataItem
,并将其设置为内部 Repeater
的 DataItem
。
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
base.OnInit(e);
BindData();
}
}
private void BindData()
{
List<CustomDataItem> dataItems = createDataTables();
outerRepeater.DataSource = dataItems;
outerRepeater.DataBind();
}
private List<CustomDataItem> createDataTables()
{
//instantiate Generic list & set capacity to 3
List<CustomDataItem> dataItems = new List<CustomDataItem>(3);
// Logic for creating example DataTable objects here
//.......
//.......
//create new CustomDataItems and add to List<>
dataItems.Add(new CustomDataItem(tbl1));
dataItems.Add(new CustomDataItem(tbl2));
dataItems.Add(new CustomDataItem(tbl3));
return dataItems;
}
protected void outerRepeater_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
if (e.Item.DataItem is CustomDataItem)
{
CustomDataItem dataItem = e.Item.DataItem as CustomDataItem;
InnerRepeaterUserControl ctrl =
e.Item.FindControl("tblInnerRep") as InnerRepeaterUserControl;
if (ctrl != null)
ctrl.DataItem = dataItem;
}
}
关注点
无。
历史
无更改。