Как я могу реализовать N-уровень вложенного контроля повторителя в asp.net?

Я хочу достичь уровня данных иерархии в использовании контроля повторителя в asp.net. Есть ли решение для достижения этой иерархии?

2 ответа

Решение

Для этого ответа я собираюсь предложить создать ваш шаблон программно - см. Здесь: https://msdn.microsoft.com/en-us/library/aa289501. Вероятно, есть какой-то способ использовать шаблоны, созданные в разметке, но это кажется более простым и определенно более гибким.

Я начинаю со страницы с просто повторителем (не шаблон)

<body>
    <form id="form1" runat="server">
    <div>
        <asp:Repeater runat="server" ID="TestRepeater">
        </asp:Repeater>
    </div>
    </form>     
</body>

и класс данных

public class DataClass
{
    public string Name { get; set; }
    public List<DataClass> Children { get; set; }
}

Для шаблона мы используем следующий класс:

public class DataTemplate : ITemplate
{
    public void InstantiateIn(Control container)
    {
        var name = new Literal();
        var repeater = new Repeater();

        name.DataBinding += BindingLiteral;
        repeater.DataBinding += BindingRepeater;

        // this here makes it recursive
        repeater.ItemTemplate = new DataTemplate();

        container.Controls.Add(name);
        container.Controls.Add(repeater);
    }

    private void BindingLiteral(object sender, System.EventArgs e)
    {
        var name = (Literal)sender;
        var container = (RepeaterItem)name.NamingContainer;
        name.Text = String.Concat("<h2>", DataBinder.Eval(container.DataItem, "Name").ToString(), "</h2>");
    }

    private void BindingRepeater(object sender, System.EventArgs e)
    {
        var name = (Repeater)sender;
        var container = (RepeaterItem)name.NamingContainer;
        name.DataSource = DataBinder.Eval(container.DataItem, "Children");
    }
}

Очевидно, вы захотите использовать более сложный шаблон. Обратите внимание, что если у вас есть шаблон в разметке, вы можете просто взять код, сгенерированный анализатором разметки, и адаптировать его к вашим потребностям.

Теперь в коде позади страницы мы просто назначаем ItemTemplate и DataSource:

public partial class Test : System.Web.UI.Page
{
    protected void Page_Init(object sender, EventArgs e)
    {
        TestRepeater.DataSource = GetTestData();
        TestRepeater.ItemTemplate = new DataTemplate();
        TestRepeater.DataBind();
    }
}

Приятно то, что ваш шаблон - это просто класс, так что вы можете добавить public Int32 Depth { get; set; } к нему, и измените сгенерированные элементы управления на основе вашей глубины.

Другое решение без создания шаблона программно:

Используя простой класс данных:

public class DataClass
{
    public string Name { get; set; }
    public List<DataClass> Children { get; set; }
}

В разметке ASPX создайте свой родительский повторитель, поместите код отображения вашего элемента в ItemTemplate и добавьте второй "пустой" повторитель:

<body>
    <form id="form1" runat="server">
    <div>
        <asp:Repeater runat="server" ID="ParentRepeater" OnItemDataBound="Repeater_ItemDataBound">
            <ItemTemplate>
                <asp:Literal runat="server" Text="<%# Eval("Name") %>"></asp:Literal>
                <asp:Repeater runat="server" ID="ChildRepeater" OnItemDataBound="Repeater_ItemDataBound" Visible="false">
                </asp:Repeater>
            </ItemTemplate>
        </asp:Repeater>
    </div>
    </form>     
</body>

И в коде позади:

protected void Repeater_ItemDataBound(object sender, RepeaterItemEventArgs e) {
    if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem) {
        DataClass currentItem = (DataClass)e.Item.DataItem;

        if (currentItem.Children.Count > 0) {
            Repeater ChildRepeater = (Repeater)e.Item.FindControl("ChildRepeater");

            ChildRepeater.DataSource = currentItem.Children;
            ChildRepeater.ItemTemplate = ParentRepeater.ItemTemplate;
            ChildRepeater.Visible = true;
            ChildRepeater.DataBind();
        }
    }
}
Другие вопросы по тегам