Как я могу реализовать 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();
}
}
}