【问题标题】:Repeater in Repeater中继器中的中继器
【发布时间】:2016-06-05 19:29:16
【问题描述】:

我在中继器中有一个中继器。父转发器绑定到Datatble,其中有一列包含Datatable

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

这可能吗?我在想我可以直接在aspx 文件中执行此操作,例如:

DataSource="<%# DataBinder.Eval(Container.DataItem, "Products")%>" 但它似乎不起作用。

【问题讨论】:

    标签: asp.net repeater nested-repeater


    【解决方案1】:

    在父中继器中,为 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>
    

    示例 (.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();
        }
    }
    

    【讨论】:

    • 使用 ItemDataBound 时总是觉得很奇怪。你有什么理由不在控制级别做吗?
    • 查看我的回答,了解使用控件DataBinding 事件的一些优势。 :)
    • 需要在if语句中加上arg.Item.ItemType == ListItemType.AlternatingItem,否则会跳过item。
    • @KalelWade 是对的。请修正这个答案,如果应该是if (args.Item.ItemType == ListItemType.Item || args.Item.ItemType == ListItemType.AlternatingItem),否则代码不会为每第二个项目启动。
    • childRepeater.DataSource = ...; ?我有一个方法,但我需要将 parentID 作为参数发送,但如何访问它?
    【解决方案2】:

    我会向子中继器本身添加一个 DataBinding 事件:

    <asp:Repeater ID="parentRepeater" runat="server">
        <asp:Repeater ID="childRepeater" runat="server"
            OnDataBinding="childRepeater_DataBinding" />
    </asp:Repeater>
    

    那就直接实现吧:

    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();
    }
    

    我更喜欢在控件级别而不是ItemDataBound 级别执行此操作,这样如果您必须删除模板中的控件或项目,您不必担心在使用的父控件中查找代码它。在他控制自己的情况下,这一切都可以本地化。另外,您永远不必发送FindControl

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

    【讨论】:

    • 所以你向子转发器添加一个数据绑定事件?以及如何获取数据源?这又是父控件数据源中的一行数据表类型?谢谢!
    • @bill 您需要从父数据源获取哪些信息才能获取新数据源?您可以通过Eval 函数访问所有当前行信息。我将更新我的答案以显示一个示例。
    • @Kelsey 您的代码不起作用,因为它以递归方式运行。而 rep.DataBind();在引发 yourRepeater_DataBinding 事件时执行。
    • 是的,出于上述原因,我更喜欢这样做。在我的应用程序中,执行DataBind() 会导致无限循环; ASP 似乎只需要设置DataSource,而不需要明确的DataBind(),以便在嵌套的Repeater 中工作。
    • @Kelsey:谢谢你的好回答,但在我的代码中 rep.DataBind() 导致了无限循环。我已经删除它,一切都很好
    【解决方案3】:

    这是如何完成的:

    DataSource='<%# ((System.Data.DataRowView)Container.DataItem)[3] %>'
    

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

    【讨论】:

      【解决方案4】:

      如果我需要这样做,我通常使用父转发器的 ItemDataBound 事件来绑定子转发器。如果 e 是您的 EventArgs 参数,您将可以通过 e.Item.FindControl() 访问子中继器,并通过 e.Item.DataItem 访问数据。

      【讨论】:

        【解决方案5】:

        Repeater1 OnItemDataBound 事件,然后是 FindControl Repeater2。 代码隐藏找不到嵌套的Repeater2!您必须使用FindControl("Repeater2")。

        protected void Repeater1_ItemDataBound(object sender, RepeaterItemEventArgs e)
        {
            if (e.Item.DataItem != null)
            {
                MemberView dataRow = (MemberView)e.Item.DataItem;
                var cat = MemberPresenter.getMemberID(dataRow.memID);
        
                Repeater rp2 = (Repeater)e.Item.FindControl("Repeater2");
                rp2.DataSource = cat;
                rp2.DataBind();
            }  
        }
        

        【讨论】:

          【解决方案6】:

          以下是如何执行此操作的示例: Article for nested repeater control

          【讨论】:

            【解决方案7】:
             protected void MainRepeater_ItemDataBound(object sender, RepeaterItemEventArgs args)
                {
                     if (args.Item.ItemType == ListItemType.Item || args.Item.ItemType == ListItemType.AlternatingItem)
                        {
                            Repeater childRepeater = (Repeater)args.Item.FindControl("ChildRepeater");
            
                            DataTable innerTable= ((DataRowView)args.Item.DataItem)["InnerTableColumnName"] as DataTable;
                            childRepeater.DataSource = tasksDetails;
                            childRepeater.DataBind();
                        }
                }
            

            【讨论】:

              猜你喜欢
              • 2019-04-17
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多