This is a migrated thread and some comments may be shown as answers.

PanelBar not working with MVC Sitemaps

4 Answers 114 Views
PanelBar
This is a migrated thread and some comments may be shown as answers.
This question is locked. New answers and comments are not allowed.
Joan Vilariño
Top achievements
Rank 2
Joan Vilariño asked on 29 Mar 2010, 08:56 AM
Hello.. I found that MVC sitemaps don't bind with you panelbar, something that is supposed to if the controls are MVC?

If I try to bind a regular SiteMap like the ones you have in your examples, all works ok, but when I try to bind something like this:

<?xml version="1.0" encoding="utf-8" ?> 
<siteMap xmlns="http://mvcsitemap.codeplex.com/schemas/MvcSiteMap-File-1.0" enableLocalization="true"
  <mvcSiteMapNode title="Home" controller="Home" action="Index" isDynamic="true" dynamicParameters="*" > 
    <mvcSiteMapNode title="Menu 1" controller="menu1" action="index" > 
      <mvcSiteMapNode title="opt1" area="area1" controller="opt1" action="index"  /> 
      </mvcSiteMapNode> 
    </mvcSiteMapNode> 
  </mvcSiteMapNode> 
</siteMap> 
 

Can you tell me if there is any way to do this? or it's not supported?

Thanks!

4 Answers, 1 is accepted

Sort by
0
Georgi Krustev
Telerik team
answered on 29 Mar 2010, 09:41 AM
Hello Joan VilariƱo,

Currently the required functionality is not supported. I will suggest you use our PITS system to vote for multi sitemap providers support.

Here is a link to the PITS item.

Kind regards,
Georgi Krustev
the Telerik team

Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items.
0
Joan Vilariño
Top achievements
Rank 2
answered on 26 Apr 2010, 04:29 PM
Well... since there is no "official" response yet, here I post my solution for anyone who needs it. It doesn't cover all the possibilities as its sized to my needs, but you can develop further from here to make it work for you:

    public static class MyTelerikExtensions 
    { 
 
        // Little hack for some nodes I need to show only if they are the  
        // current navigator node, else they're hidden. 
        private static bool ShowNode(MvcSiteMapNode node) 
        { 
            return (node != null && 
                    (nodo.Visibility == MvcSiteMapNodeVisibility.Full || node.Equals(SiteMap.CurrentNode))); 
        } 
 
        // I use this to make a node "parent node" (no url on click) 
        // when it has visible childs, or link (url on click) if  
        // it has. 
        private static bool HasVisibleChild(MvcSiteMapNode node) 
        { 
            if (node != null && node.HasChildNodes) 
                foreach (MvcSiteMapNode subnode in node.ChildNodes) 
                    if (subnode.Visibility == MvcSiteMapNodeVisibility.Full || HasVisibleChild(subnode)) 
                        return true
 
            return false
        } 
 
        // Generate a panelbaritem from a mvc node 
        private static PanelBarItem GetMvcSiteMapNode(MvcSiteMapNode node) 
        { 
            if (node != null
            { 
                var result = new PanelBarItem(); 
                result.Text = node.Title; 
                if (!node.HasChildNodes || !HasVisibleChild(node)) 
                { 
                    if (!string.IsNullOrEmpty(node.Action)) 
                        result.ActionName = node.Action; 
                    if (!string.IsNullOrEmpty(node.Controller)) 
                        result.ControllerName = node.Controller; 
                    if (!string.IsNullOrEmpty(node.Url)) 
                        result.Url = node.Url; 
                } 
                result.ImageUrl = node.ImageUrl; 
                result.Expanded = false
                result.Visible = true
                if (node.HasChildNodes) 
                    foreach (MvcSiteMapNode subnode in node.ChildNodes) 
                        if (ShowNode(subnode)) 
                            result.Items.Add(GetMvcSiteMapNode(subnode as MvcSiteMapNode)); 
                return result; 
            } 
            else return new PanelBarItem(); 
        } 
 
        public static PanelBarBuilder BindToMvcSitemap(this PanelBarBuilder panelbar, SiteMapNode node) 
        { 
            if (node != null
            { 
                var component = panelbar.ToComponent(); 
                IList<PanelBarItem> items = component.Items; 
                var rootItem = new PanelBarItem() {Enabled = true, Visible = true, Expanded = true, Text = node.Title}; 
                foreach (MvcSiteMapNode subnode in node.ChildNodes) 
                    if (ShowNode(subnode)) 
                        rootItem.Items.Add(GetMvcSiteMapNode(subnode as MvcSiteMapNode)); 
                items.Add(rootItem); 
            } 
            return panelbar; 
        } 
    } 

To use this method in your .ascx files... do like this:

<
     Html.Telerik().PanelBar() 
                   .Name("PanelBarMenu") 
                   .ExpandMode(PanelBarExpandMode.Single) 
                   .BindToMvcSitemap(SiteMap.RootNode) 
                   .Render(); 
 %> 

Hope this helps someone !! 


0
David
Top achievements
Rank 1
answered on 21 Jul 2010, 11:12 AM
Thanks Joan It helps !
 
And I adapted it to menu :

namespace Telerik.Web.Mvc.UI
{
    public static class MenuExtension
    {
        // Little hack for some nodes I need to show only if they are the 
        // current navigator node, else they're hidden.
        private static bool ShowNode(MvcSiteMapNode node)
        {
            return (node != null &&
                    (node.Equals(SiteMap.CurrentNode)));
        }
 
        // I use this to make a node "parent node" (no url on click)
        // when it has visible childs, or link (url on click) if 
        // it has.
        private static bool HasVisibleChild(MvcSiteMapNode node)
        {
            if (node != null && node.HasChildNodes)
            {
                foreach (MvcSiteMapNode subnode in node.ChildNodes)
                {
                    if (HasVisibleChild(subnode))
                    {
                        return true;
                    }
                }
            }
 
            return false;
        }
 
        // Generate a menuitem from a mvc node
        private static MenuItem GetMvcSiteMapNode(MvcSiteMapNode node)
        {
            if (node != null)
            {
                var result = new MenuItem();
                result.Text = node.Title;
                if (!node.HasChildNodes || !HasVisibleChild(node))
                {
                    if (!string.IsNullOrEmpty(node.Action))
                        result.ActionName = node.Action;
                    if (!string.IsNullOrEmpty(node.Controller))
                        result.ControllerName = node.Controller;
                    if (!string.IsNullOrEmpty(node.Url))
                        result.Url = node.Url;
                }
 
                result.ImageUrl = node.ImageUrl;
                result.ImageHtmlAttributes.Add("style", "width:32px");
                result.Visible = true;
                
                if (node.HasChildNodes)
                {
                    foreach (MvcSiteMapNode subnode in node.ChildNodes)
                    {
                        //if (ShowNode(subnode))
                        result.Items.Add(GetMvcSiteMapNode(subnode as MvcSiteMapNode));
                    }
                }
 
                return result;
            }
            else
                return new MenuItem();
        }
 
        public static MenuBuilder BindToMvcSitemap(this MenuBuilder menu, System.Web.SiteMapNode node)
        {
            if (node != null)
            {
                var component = menu.ToComponent();
                IList<MenuItem> items = component.Items;
                //var rootItem = new MenuItem() { Enabled = true, Visible = true, Text = node.Title };
                 
                foreach (MvcSiteMapNode subnode in node.ChildNodes)
                {
                    items.Add(GetMvcSiteMapNode(subnode as MvcSiteMapNode));
                }
 
                //items.Add(rootItem);
            }
            return menu;
        }
    }
}

My sitemap have a root node with one item so  I directly take childnode of the root node like you can see in commented lines in
BindToMvcSitemap.


0
Joan Vilariño
Top achievements
Rank 2
answered on 21 Jul 2010, 11:40 AM
Nice to know... I'm glad someone found it useful...

Cheers
Tags
PanelBar
Asked by
Joan Vilariño
Top achievements
Rank 2
Answers by
Georgi Krustev
Telerik team
Joan Vilariño
Top achievements
Rank 2
David
Top achievements
Rank 1
Share this question
or