我正在构建一个弹出菜单,客户希望它能够根据层次结构不断弹出。
例如,第一个窗格是选项列表。当它们悬停在上面时,另一个窗格应该弹出旁边的下一级选项,依此类推,直到达到最后一级选项。
我可以处理所有的javascript和东西,但我想不出一种方法可以在转发器中不断嵌入转发器。我知道我可以通过将转发器放在另一个转发器中来做一次,但之后我只有两层。
我需要能够为每一层选项不断嵌入转发器,或者使用不同控件的类似技术实现这一点。
任何帮助都很棒,谢谢!
答案 0 :(得分:0)
您将无法在标记中构建此内容。您必须通过为每个级别构建Repeater并将其添加到先前的Repeater模板中,在代码中动态添加控件。它将需要对所选的每个选项进行完全回发,因为嵌套的Repeater可能具有不同的深度,具体取决于所选的选项。
但是,使用AJAX和javascript,你可能会更好地做所有客户端。选择某个选项后,将触发AJAX请求以查看该选项是否包含子选项。如果确实如此(返回它们),则使用javascript动态构建新的选项控件并将其添加到页面中。选择其他选项后,您将从DOM中删除包含先前选择的子选项的元素。
答案 1 :(得分:0)
如果您可以以MenuItem
个对象列表的形式显示您的菜单,每个对象都有一个(有时是空的)子项列表(我的意思是List<MenuItem>
。我们将使用此集合作为子转发器的数据源,因此它需要实现IEnumerable<T>
)作为属性MenuItem.SubItems
,您可以使用UserControl
它会循环出一个菜单级别,然后自己调用下一个菜单级别。
在UserControl
你有类似的东西:
<li><a href='<%= this.MenuItem.Url %>'><%= this.MenuItem.LinkText %></a></li>
<asp:Repeater ID="UCRepeater" runat="server">
<HeaderTemplate>
<ul>
<ItemTemplate>
<menu:MenuItem ID="MenuItemUC" runat="server" />
</ItemTemplate>
<FooterTemplate>
</ul>
</FooterTemplate>
</asp:Repeater>
UserControl
中的ItemTemplate
是相同的,因此对于每个项目模板,都会呈现相同的内容。
以下是此用户控件的Code Behind,这就是魔术发生的地方:
public partial class MenuItemUserControl : UserControl
{
// A property we'll use as the data source
public MenuItem MenuItem { get; set; }
protected void Page_Load(object sender, EventArgs e)
{
// If the current menu item has sub items, we bind the repeater to them
// And by the way, there is no use doing this on every postback. First
// page load is good enough...
if(!Page.IsPostBack) {
{
if(MenuItem.SubItems.Count > 0)
{
UCRepeater.DataSource = MenuItem.SubItems;
UCRepeater.DataBind();
}
}
}
protected void UCRepeater_OnItemDataBound(object sender,
RepeaterDataBoundEventArgs e)
{
// Every time an Item is bound to the repeater, we take the current
// item which will be contained in e.DataItem, and set it as the
// MenuItem on the UserControl
// We only want to do this for the <ItemTemplate> and
// <AlternatingItemTemplate>
if(e.Item.ItemType == ListItemType.Item ||
e.Item.ItemType == ListItemType.AlternatingItem)
{
var uc = (MenuItemUserControl)e.Item.FindControl("MenuItemUC");
if(uc != null)
{
// This is the magic. Abrakadabra!
uc.MenuItem = (MenuItem)e.DataItem;
}
}
}
}
因此,为了使其工作,唯一缺少的是将数据作为MenuItem
的分层列表获取的一种很好的方法。这将留给您的数据访问层(使用LINQ to SQL或Entity Framework简单易用;))
免责声明:此代码是按原样提供的,我把它写在了我的头顶。我没有对它进行测试,但我认为它会起作用 - 如果没有,它至少可以让你知道如何解决问题。如果您有问题,请在评论中发布,我会尽力帮助 - 但这里没有成功的承诺。只是愿意帮帮忙! =)