本文介绍了如何在ASP.NET中嵌套中继器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要知道如何在用户控件中嵌套中继器。 html方面很好,这是我需要帮助的背后的绑定和代码。我只能使用sql数据源查找示例,但这并没有真正的帮助。

I need to know how to nest repeaters within a user control. The html side of things is fine, it's the binding and code behind I need help with. I've only been able to find examples using an sql data source, which doesn't really help.

我的中继器如下所示:

<asp:Panel ID="pnlDiscipline" runat="server" CssClass="">
    <asp:Repeater ID="rptDiscipline" runat="server">
        <ItemTemplate>
            <h4><%#Eval("Discipline")%></h4>
            <ul>
                <asp:Repeater ID="rptPrograms" runat="server">
                    <ItemTemplate>
                        <li><asp:HyperLink runat="server" Text='<%#Eval("Name") %>' NavigateUrl='<%#Eval("Link") %>'></asp:HyperLink> <%#Eval ("Notation") %></li>
                    </ItemTemplate>
                </asp:Repeater>
            </ul>
        </ItemTemplate>
    </asp:Repeater>

我需要做的是希望可以合理地弄清楚-h4学科应该出现一次,下面列出了该学科的所有条目,然后是下一个h4,然后是适当的列表,下一个h4,依此类推。

What I need to do is hopefully reasonably clear - the h4 discipline should appear once, all the entries that belong to the discipline are listed below, then the next h4, then the appropriate list, the next h4 and so on.

数据源是在代码背后创建的数据视图,其中每一行都有名称,链接,注释和纪律,我已将数据视图绑定到最外层的转发器,并且其行为符合预期-列出每个条目的学科名称,但在内部中继器中不显示任何数据。

The datasource is a dataview created in the codebehind where each row has 'Name', "Link', 'NOtation' and 'Discipline'. I've bound the dataview to the outermost repeater, and it behaves as expected - lists the discipline name for each entry, but shows no data in the inner repeater.

我该如何进行这项工作?

How do I go about making this work?

编辑:为了澄清,我在代码的后面有一个数据表,该表中的每一行都是一个项目,每个项目都属于一个学科,我想使用外部中继器列出这些学科,

Just to clarify, I have one datatable in the codebehind. Each row in that table is an item, each item belongs to a discipline. I want to use the outer repeater to list the disciplines, the inner to list the items grouped under each discipline. Like so:

<h4>DISCIPLINE 1</h4>
    <ul>
        <li>Item</li>
        <li>Item</li>
        <li>Item</li>
    </ul>
<h4>DISCIPLINE 2</h4>
    <ul>
        <li>Item</li>
        <li>Item</li>
    </ul>
<h4>DISCIPLINE 3</h4>
    <ul>
        <li>Item</li>
        <li>Item</li>
    </ul>

目前,将数据表绑定到外部中继器可以做到这一点(示例使用上面的数据): / p>

At present, binding the datatable to the outer repeater gives this (example uses the data above):

    <h4>DISCIPLINE 1</h4>
    <h4>DISCIPLINE 1</h4>
    <h4>DISCIPLINE 1</h4>
    <h4>DISCIPLINE 2</h4>
    <h4>DISCIPLINE 2</h4>
    <h4>DISCIPLINE 3</h4>
    <h4>DISCIPLINE 3</h4>

我已经按照建议在外部中继器上使用了OnItemDataBound,并且作为测试用例,它能够访问数据:

I've used OnItemDataBound on the outer repeater as suggested, and as a test case am able to access the data:

protected void rptDiscipline_ItemDataBound(Object Sender, RepeaterItemEventArgs e)
{
    DataRowView drView = (DataRowView) e.Item.DataItem;
    string name = drView["Name"] as string;
    string link = drView["Link"] as string;
    string notation = drView["Notation"] as string;
    Response.Write(name + link + notation + "<br />")
}

数据就在那里,这正是我期望看到的,我只是无法将其绑定到内部中继器。如果有更高性能的方法可以实现此目的,我很乐意重新设计解决方案。

So the data is there, it is exactly what I would expect to see, I just can't get it bound to the inner repeater. If there is a more performant way to achieve the same, I'm happy to rework my solution.

推荐答案

在外部控件上,请使用ItemDataBound事件,如下所示:

On the outer control, use the ItemDataBound event, like this:

<asp:Repeater ID="rptDiscipline" runat="server"
     OnItemDataBound="rptDiscipline_ItemDataBound">
...

然后,在后面的代码中,处理rptDisciplineline_ItemDataBound事件并手动进行绑定内部中继器。中继器的ItemDataBound事件针对重复的每个项目触发一次。因此,您将执行以下操作:

Then, in the code-behind, handle the rptDiscipline_ItemDataBound event and manually bind the inner repeater. The repeater's ItemDataBound event fires once for each item that is repeated. So you'll do something like this:

protected void rptDiscipline_ItemDataBound(Object Sender, RepeaterItemEventArgs e)
{
    // To get your data item, cast e.Item.DataItem to
    // whatever you're using for the data object; for example a DataRow.

    // Get the inner repeater:
    Repeater rptPrograms = (Repeater) e.Item.FindControl("rptPrograms");

    // Set the inner repeater's datasource to whatever it needs to be.
    rptPrograms.DataSource = ...
    rptPrograms.DataMember = ...
    rptPrograms.DataBind();
}

编辑:已更新以匹配您问题的更新。

Updated to match your question's update.

您需要将外部中继器绑定到一个数据源,该数据源每个要呈现该中继器的项都只有一个记录。这意味着数据源需要是仅包含学科的集合/列表/数据表/等。在您的情况下,我建议从DataTable中为内部集合获取 List< string> 学科,并将外部中继器绑定到该内部。然后,内部中继器使用ItemDataBound事件绑定到DataTable中数据的子集。要获取该子集,请通过DataView过滤DataTable。

You need to bind the outer repeater to a data source that has only one record per item you want the repeater to render. That means the data source needs to be a collection/list/datatable/etc that has only the disciplines in it. In your case, I would recommend getting a List<string> of disciplines from the DataTable for the inner collection, and bind the outer repeater to that. Then, the inner repeater binds to a subset of the data in the DataTable, using the ItemDataBound event. To get the subset, filter the DataTable through a DataView.

以下代码:

protected void Page_Load(object sender, EventItems e)
{
    // get your data table
    DataTable table = ...

    if ( !IsPostBack )
    {
        // get a distinct list of disciplines
        List<string> disciplines = new List<string>();
        foreach ( DataRow row in table )
        {
            string discipline = (string) row["Discipline"];
            if ( !disciplines.Contains( discipline ) )
                disciplines.Add( discipline );
        }
        disciplines.Sort();

        // Bind the outer repeater
        rptDiscipline.DataSource = disciplines;
        rptDiscipline.DataBind();
    }
}

protected void rptDiscipline_ItemDataBound(Object Sender, RepeaterItemEventArgs e)
{
    // To get your data item, cast e.Item.DataItem to
    // whatever you're using for the data object
    string discipline = (string) e.Item.DataItem;

    // Get the inner repeater:
    Repeater rptPrograms = (Repeater) e.Item.FindControl("rptPrograms");

    // Create a filtered view of the data that shows only
    // the disciplines needed for this row
    // table is the datatable that was originally bound to the outer repeater
    DataView dv = new DataView( table );
    dv.RowFilter = String.Format("Discipline = '{0}'", discipline);

    // Set the inner repeater's datasource to whatever it needs to be.
    rptPrograms.DataSource = dv;
    rptPrograms.DataBind();
}

这篇关于如何在ASP.NET中嵌套中继器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-24 21:53