中继器中的中继器

bil*_*ill 42 asp.net repeater nested-repeater

我在转发器里面有一个转发器.父转发器绑定到Datatble其中包含a的列的位置Datatable.

我想将子转发器绑定到父转发器的数据行中的数据表列

这可能吗?我想我可以直接在aspx文件中这样做:

DataSource="<%# DataBinder.Eval(Container.DataItem, "Products")%>" 但它似乎没有用.

Ant*_*ton 77

在父转发器中,将方法附加到OnItemDataBound事件,并在方法中查找嵌套转发器并将数据绑定到它.

示例(.aspx):

<asp:Repeater ID="ParentRepeater" runat="server" OnItemDataBound="ItemBound">
    <ItemTemplate>
        <!-- Repeated data -->
        <asp:Repeater ID="ChildRepeater" runat="server">
            <ItemTemplate>
                <!-- Nested repeated data -->
            </ItemTemplate>
        </asp:Repeater>
    </ItemTemplate>
</asp:Repeater>
Run Code Online (Sandbox Code Playgroud)

示例(.cs):

protected void Page_Load(object sender, EventArgs e)
{
    if (!IsPostBack)
    {
        ParentRepeater.DataSource = ...;
        ParentRepeater.DataBind();
    }
}

protected void ItemBound(object sender, RepeaterItemEventArgs args)
{
    if (args.Item.ItemType == ListItemType.Item || args.Item.ItemType == ListItemType.AlternatingItem)
    {
        Repeater childRepeater = (Repeater)args.Item.FindControl("ChildRepeater");
        childRepeater.DataSource = ...;
        childRepeater.DataBind();
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 你需要在if语句中添加arg.Item.ItemType == ListItemType.AlternatingItem,否则你将跳过项目. (3认同)
  • @KalelWade是对的.请修复这个答案,if if shoold是`if(args.Item.ItemType == ListItemType.Item || args.Item.ItemType == ListItemType.AlternatingItem)`否则代码不会为每个第二项启动. (2认同)

Kel*_*sey 24

我会将一个DataBinding事件添加到子转发器本身:

<asp:Repeater ID="parentRepeater" runat="server">
    <asp:Repeater ID="childRepeater" runat="server"
        OnDataBinding="childRepeater_DataBinding" />
</asp:Repeater>
Run Code Online (Sandbox Code Playgroud)

然后实现它:

protected void childRepeater_DataBinding(object sender, System.EventArgs e)
{
    Repeater rep = (Repeater)(sender);

    int someIdFromParentDataSource = (int)(Eval("ParentID"));

    // Assuming you have a function call `GetSomeData` that will return
    // the data you want to bind to your child repeater.
    rep.DataSource = GetSomeData(int);
    rep.DataBind();
}
Run Code Online (Sandbox Code Playgroud)

我更喜欢在控件级别而不是ItemDataBound级别上执行此操作,因此如果您必须删除模板中的控件或项目,则不必担心在使用它的父控件中查找代码.它控制了自己的所有本地化.另外,你永远不必做FindControl.

如果你想在将来替换一个控件,你可以删除它,你的代码仍然可以工作,因为它都是自包含的.使用ItemDataBound会导致代码仍然编译但在运行时崩溃或意外行为,因为它依赖于子控件.

  • @Kelsey您的代码不起作用,因为它以递归方式运行.而rep.DataBind(); 执行事件yourRepeater_DataBinding被引发. (8认同)
  • 是的,出于上述原因,我更喜欢这样做.在我的应用程序中,执行`DataBind()`会导致无限循环; ASP似乎只需要设置`DataSource`,而不需要显式的`DataBind()`,以便在嵌套的`Repeater`中工作. (2认同)
  • @Kelsey:谢谢您的好回答,但是在我的代码中rep.DataBind()导致了无限循环。我已经删除了,一切都很好 (2认同)

bil*_*ill 8

以下是它的完成方式:

DataSource='<%# ((System.Data.DataRowView)Container.DataItem)[3] %>'
Run Code Online (Sandbox Code Playgroud)

因此,如果您知道父表中包含嵌套转发器的子表/数据源的列,则可以将其直接放在aspx文件中.