如何在 asp.net 中实现 N 级嵌套 Repeater 控件?
How can I Implement N level nested Repeater control in asp.net?
我想在 asp.net 中使用转发器控件实现 n 级数据层次结构。
是否有任何解决方案来实现该层次结构?
对于这个答案,我建议以编程方式创建模板 - 请参阅此处: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>
和一个数据class
public class DataClass
{
public string Name { get; set; }
public List<DataClass> Children { get; set; }
}
对于模板,我们使用以下 class:
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();
}
}
好的是您的模板只是一个 class,因此您可以向其添加一个 public Int32 Depth { get; set; }
,并根据您的深度更改生成的控件。
另一种解决方案,无需以编程方式创建模板:
使用简单的数据class :
public class DataClass
{
public string Name { get; set; }
public List<DataClass> Children { get; set; }
}
在 ASPX 标记中创建您的父转发器,将您的项目显示代码放入 ItemTemplate,然后添加第二个 "empty" 转发器:
<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();
}
}
}
我想在 asp.net 中使用转发器控件实现 n 级数据层次结构。 是否有任何解决方案来实现该层次结构?
对于这个答案,我建议以编程方式创建模板 - 请参阅此处: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>
和一个数据class
public class DataClass
{
public string Name { get; set; }
public List<DataClass> Children { get; set; }
}
对于模板,我们使用以下 class:
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();
}
}
好的是您的模板只是一个 class,因此您可以向其添加一个 public Int32 Depth { get; set; }
,并根据您的深度更改生成的控件。
另一种解决方案,无需以编程方式创建模板:
使用简单的数据class :
public class DataClass
{
public string Name { get; set; }
public List<DataClass> Children { get; set; }
}
在 ASPX 标记中创建您的父转发器,将您的项目显示代码放入 ItemTemplate,然后添加第二个 "empty" 转发器:
<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();
}
}
}