0

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

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

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

我需要能够为每一层选项持续嵌入中继器,或者使用不同的控件通过类似的技术来实现这一点。

任何帮助都很棒,谢谢!

4

2 回答 2

0

您将无法在标记中构建它。您必须在代码中动态添加控件,方法是为每个级别构建中继器并将其添加到前一个中继器的模板中。它需要对每个选择的选项进行完整的回发,因为嵌套的中继器可能具有不同的深度,具体取决于选择的选项。

不过,使用 AJAX 和 javascript 在所有客户端执行此操作可能会更好。选择选项时,请从Ajax请求中触发,以查看该选项是否具有子选项。如果是(返回它们),则使用 javascript 动态构建新的选项控件并将其添加到页面中。选择不同的选项时,您将从包含先前所选选项子选项中的DOM中删除元素。

于 2009-05-31T11:55:44.577 回答
0

如果您可以以MenuItem对象列表的形式获取菜单,每个对象都有一个(有时是空的)子项目列表(我的意思是List<MenuItem>这里......我们将使用这个集合作为数据源一个子中继器,所以它需要实现IEnumerable<T>) 作为一个属性MenuItem.SubItems,你可能会使用一个UserControl循环出一个菜单级别的 a ,并在下一个菜单级别调用它自己。

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相同的,因此对于每个项目模板,将呈现相同的内容。

下面是这个用户控件的代码,这就是神奇的地方:

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;
            }
        }

    }
}

所以为了让它工作,唯一缺少的是一个很好的方法,可以将数据作为MenuItems 的分层列表取出。我将把这个留给您的数据访问层(使用 LINQ to SQL 或实体框架会很便宜...;))

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

于 2009-05-31T12:13:35.430 回答