如何动态添加/修改ASP MenuItems?

时间:2017-04-18 11:00:39

标签: c# asp.net webforms

Asp:连接到asp:SiteMapDataSource的MasterPage上的菜单控件。

目标

在应用程序开始时动态地将多个子菜单项添加到其中一个菜单项。

创意1 - 自定义SiteMapProvider

似乎重新发明轮子。

创意2 - 自定义SiteMapResolveEventHandler

我尝试了以下操作,但它没有任何(可见)效果。

// In Site.Master.cs
protected void Page_Init(object sender, EventArgs e)
{
    SiteMap.SiteMapResolve += new SiteMapResolveEventHandler(GenerateSubMenu);
}

private SiteMapNode GenerateSubMenu(Object sender, SitemapResolveEventArgs e)
{
    SiteMapNode currentNode = SiteMap.CurrentNode?.Clone(true);
    if (currentNode == null) return null;
    currentNode.Title = "TEST";
    return currentNode; // Displayed Menu doesn't change
}

创意3 - 修改MenuControl的项目集合

我尝试修改菜单控件事件中的menuItems: 在OnInit和OnLoad事件中,Items Collection为空。

var menu = (Menu)sender;
if (menu.Items.Count < 4) return; // always is 0
var item = menu.Items[3];

1 个答案:

答案 0 :(得分:0)

我成功地实现了创意2。 基本上,我是在第一次调用SiteMapResolveHandler时将动态节点添加到站点地图的内存中表示。

// Site.Master.cs
protected void Page_Init(object sender, EventArgs e)
{
    SiteMap.SiteMapResolve += new SiteMapResolveEventHandler(GenerateSubMenu);
}

private static bool siteMapModified = false;

private SiteMapNode GenerateSubMenu(Object sender, SitemapResolveEventArgs e)
{
    if (!siteMapModified)
    {
        var rootChildNodes = SiteMap.RootNode.ChildNodes;
        if (rootChildNodes.Count > 3)
        {
            siteMapModified = true;
            var targetNode = rootChildNodes[3];
            targetNode.ReadOnly = false;

            // create writeable collection
            var childNodes = new SiteMapNodeCollection(targetNode.ChildNodes);

            var statusUrl = VirtualPathUtility.ToAbsolute("~/Content/status.aspx");

            var elements= LoadDynamicElements();
            foreach (var element in elements)
            {
                childNodes.Add(
                    new SiteMapNode(
                        targetNode.Provider, 
                        element, 
                        statusUrl + "?k=" + element, 
                        element));
            }

            targetNode.ChildNodes = childNodes;
       }
   }

   return SiteMap.CurrentNode;
}