如何堆叠未知数量的ASP.NET中继器?

时间:2009-05-31 11:16:25

标签: asp.net repeater menu

我正在构建一个弹出菜单,客户希望它能够根据层次结构不断弹出。

例如,第一个窗格是选项列表。当它们悬停在上面时,另一个窗格应该弹出旁边的下一级选项,依此类推,直到达到最后一级选项。

我可以处理所有的javascript和东西,但我想不出一种方法可以在转发器中不断嵌入转发器。我知道我可以通过将转发器放在另一个转发器中来做一次,但之后我只有两层。

我需要能够为每一层选项不断嵌入转发器,或者使用不同控件的类似技术实现这一点。

任何帮助都很棒,谢谢!

2 个答案:

答案 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简单易用;))

免责声明:此代码是按原样提供的,我把它写在了我的头顶。我没有对它进行测试,但我认为它会起作用 - 如果没有,它至少可以让你知道如何解决问题。如果您有问题,请在评论中发布,我会尽力帮助 - 但这里没有成功的承诺。只是愿意帮帮忙! =)