How To Create A Nested LinkButtons Inside A Repeater?

好久不见. 提交于 2019-12-02 07:11:16
NakedBrunch

The following example uses a ListView instead of a Repeater. ListViews are great because they'll give you much more flexibility over a Repeater. Moreover, as you can see in the sample code below, binding the nested/child ListView can all be done declaratively without any code-behind.

Example of what the following code will produce

ASPX

<asp:ListView runat="server" ID="lvw">
    <LayoutTemplate>
        <ul>
            <li id="itemPlaceholder" runat="server" />
        </ul>
    </LayoutTemplate>
    <ItemTemplate>
        <li>    
            <asp:LinkButton runat="server" CommandArgument='<%# Eval("Name")%>'><%# Eval("Name")%></asp:LinkButton>
            <asp:ListView runat="server" ID="lvw2" DataSource='<%# Eval("Children")%>'>
                <LayoutTemplate>
                    <ul>
                        <li id="itemPlaceholder" runat="server" />
                    </ul>
                </LayoutTemplate>
                <ItemTemplate>
                    <li><asp:LinkButton runat="server" CommandArgument='<%# Eval("Name")%>'><%# Eval("Name")%></asp:LinkButton></li>
                </ItemTemplate>
            </asp:ListView>
        </li>
    </ItemTemplate>
</asp:ListView>

C#

lvw.DataSource = personList;
lvw.DataBind();

As you can see, in the C# code, I've created a list of "Person" as follows. Each Person object has a list of child Person objects. By creating your objects in this manner, binding the ListView is really as simple as I've shown. Use the Person object below to run a quick sample so you can see for yourself.

Person object

public class Person
{
    public string name { get; set; }
    public List<Person> Children { get; set; }
}

For your test, you can create a Page_Load method as follows:

protected void Page_Load(object sender, EventArgs e)
    {
        List<Person> personList = new List<Person>();
        Person person1 = new Person() { name = "Child 1" };
        Person person2 = new Person() { name = "Child 2" };
        List<Person> childPersonList1 = new List<Person>();
        childPersonList1.Add(person1);
        childPersonList1.Add(person2);
        Person person3 = new Person() { name = "Person 1" };
        person3.Children = childPersonList1;
        personList.Add(person3);
        Person person4 = new Person() { name = "Child 3" };
        Person person5 = new Person() { name = "Child 4" };
        List<Person> childPersonList2 = new List<Person>();
        childPersonList2.Add(person4);
        childPersonList2.Add(person5);
        Person person6 = new Person() { name = "Person 2" };
        person6.Children = childPersonList2;
        personList.Add(person6);
        Person person7 = new Person() { name = "Child 5" };
        Person person8 = new Person() { name = "Child 6" };
        List<Person> childPersonList3 = new List<Person>();
        childPersonList3.Add(person7);
        childPersonList3.Add(person8);
        Person person9 = new Person() { name = "Person 3" };
        person9.Children = childPersonList3;
        personList.Add(person9);

        lvw.DataSource = personList;
        lvw.DataBind();
    }

See the following StackOverflow question to learn more about the differences between a Repeater and a ListView: Repeater, ListView, DataList, DataGrid, GridView ... Which to choose?

I would recommend doing a repeater inside of a repeater.

<asp:Repeater id="rptParentLinkButtons" runat="server">
    <asp:LinkButton id="lnkParentbutton" runat="server" Text="<% Eval("ParentText") %>" />
    <ItemTemplate>
        <asp:Repeater id="rptChildLinkButtons" runat="server" DataSource='<% Eval("ChildElements") %>' >
            <ItemTemplate>
                <asp:LinkButton id="lnkChildButton" runat="server" text="<% Eval("ChildText") %>" />
            </ItemTemplate>
        </asp:Repeater>
    </ItemTemplate>
</asp:Repeater>

And then in the ItemDataBound events you can set the data source for the child repeater and bind it.

Feel free to ask for any clarifications. i don't want to write the whole thing for you.

EDIT:

To bind the parent, you would want to use Page Load or some other page event to add the datasource to the outer repeater and then bind it.

protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);

            rptParentLinkButtons.DataSource = myParentItemCollection;
            rptParentLinkButtons.DataBind();
        }

And then you have 2 options, wither the way I showed it in the asp above by accessing your databound object using the eval, or by using the parent's ItemDataBound event.

void rptParentLinkButtons_ItemDataBound(Object Sender, RepeaterItemEventArgs e) {

          // This event is raised for the header, the footer, separators, and items.

          Repeater childRepeater = (Repeater)e.Item.FindControl("rptChildLinkButtons");
          // Set the source of the child equal to a collection on the parent object for it to make the child links.
          childRepeater.DataSource = myParentItemCollection[e.Item.ItemIndex].childElements;
       }    

The above code is not perfect, but it should get you a good idea on how to get the rest of the way,

Cheers,

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!