-->

How To Create A Nested LinkButtons Inside A Repeat

2020-04-23 04:29发布

问题:

I need to create a nested linkbuttons in a asp.net page that looks like a treeview, but all are linkbuttons. Example is shown below:

ParentLinkButton1
    ChildLinkButton1
    ChildLinkButton2
    ChildLinkButton3
ParentLinkButton2
    ChildLinkButton1
    ChildLinkButton2
ParentLinkButton3
ParentLinkButton4
    ChildLinkButton1

I really don't know how to do this. Based on my research this can be done using repeated control but I don't know how to do that... Please if you can teach me step by step...

Thanks in advance!

回答1:

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?



回答2:

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,