+1-888-365-2779
Try Now
More in this section
Categories
Bloggers
Blogs RSS feed

SiteMenu Builder

by Ivan Dimitrov

This post will show you how to create custom navigation menu for your website, where you can specify which pages you want to see and which not. There are many cases where you want to have two level navigation or several navigational  menus. Each time you will have to do some coding over the menu so that it will start showing the appropriate items/nodes.

In this post I am creating a custom class that inherits from WebUITypeEditor.

First I am going to build WebUITypeEditor using RadTreeView control which supports multiple selection. This seems to be the most appropriate control to achieve my goal. I will bind the control to a list containing all pages by using the CmsManager.GetPages() method. Then I will return the ID of each node to my property as a Guid array.

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Telerik.Cms.Web.UI;
using Telerik.Web.UI;
using Telerik.Framework.Web;
using Telerik.Cms;
using System.Collections;
using System.Web.UI;
using Telerik.Cms.Web;
 
/// <summary>
/// Summary description for DynamicMenuBuilderWebUITypeEditor
/// </summary>
public class DynamicMenuBuilderWebUITypeEditor : WebUITypeEditor<Guid[]>
{
    public DynamicMenuBuilderWebUITypeEditor()
    {
 
    }
 
    public override Guid[] Value
    {
        get
        {
            Guid pageId = Guid.Empty;
            List<Guid> selectedIds = new List<Guid>();
            foreach (RadTreeNode node in TreeView.SelectedNodes)
            {
                if (node != null)
                {
                    CmsSiteMapNode smNode = (CmsSiteMapNode)SiteMap.Provider.FindSiteMapNode("~/" + node.FullPath + ".aspx");
                    ICmsPage cmsPage = manager.GetPage(smNode.CmsPage.ID) as ICmsPage;
                    pageId = cmsPage.ID;
                    selectedIds.Add(pageId);
                }
            }
            return selectedIds.ToArray();
        }
        set
        {
            this.ViewState["selectedPage"] = value;
            base.ChildControlsCreated = false;
        }
    }
 
    public string Templte
    {
        get
        {
            object o = this.ViewState["Template"];
            if (o == null)
                return ("~/CustomControls/PageIDWebEditor.ascx");
            return (string)o;
        }
        set
        {
            this.ViewState["Template"] = value;
        }
    }
    
 
    protected override void CreateChildControls()
    {
        base.CreateChildControls();
        this.manager = new CmsManager();
        this.template = ControlUtils.GetTemplate<SelectorTemplate>(this.Templte);
        this.template.InstantiateIn(this);
        var manager = new CmsManager();
        IList allPages = manager.GetPages();
        TreeView.MultipleSelect = true;
        TreeView.DataSource = allPages;
        TreeView.DataTextField = "MenuName";
        TreeView.DataFieldParentID = "ParentID";
        TreeView.DataFieldID = "ID";
        TreeView.DataNavigateUrlField = "StaticUrl";
        TreeView.DataBind();
    }
 
    protected virtual RadTreeView TreeView
    {
        get
        {
            return this.Controls[0].FindControl("RadTreeView1") as RadTreeView;
        }
    }
 
    public class SelectorTemplate : ITemplate
    {
        public void InstantiateIn(Control container)
        {
        }
    }
 
    private ITemplate template;
    private CmsManager manager;
 
}

My Selector template is shown below. I declared there a RadTreeView instance:

<%@ Control Language="C#" AutoEventWireup="true" CodeFile="PageIDWebEditor.ascx.cs" Inherits="CustomControls_PageIDWebEditor" %>
 
 
<asp:Label runat="server" ID="Label1" Text="Select a page from the tree" />
<telerik:RadTreeView ID="RadTreeView1" runat="server" Skin="Black"/>

In the code behind I have to disable the NavigateUrl as otherwise when a node is selected a postback will appear, which will clear the selected nodes collection.

public partial class CustomControls_PageIDWebEditor : System.Web.UI.UserControl
{
    protected void Page_Load(object sender, EventArgs e)
    {
        RadTreeView1.NodeDataBound += new Telerik.Web.UI.RadTreeViewEventHandler(RadTeerView1_NodeDataBound);
    }
 
    void RadTeerView1_NodeDataBound(object sender, Telerik.Web.UI.RadTreeNodeEventArgs e)
    {
        foreach (RadTreeNode node in RadTreeView1.GetAllNodes())
        {
            node.NavigateUrl = "";
        }
    }
}

My selector is ready and now I need a custom control. The custom control will inherit from the well know CompositeControl class. This custom control does not need a template, because the SiteMenu will be dynamically generated.

I need a ViewState property from where I will call the WebUITypeEditor. I will use the built-in GuidArrayConverter, so that I will not have to create a custom DictionaryConverter for my property that is not just a simple string

[WebEditor("DynamicMenuBuilderWebUITypeEditor, App_Code")]
    [TypeConverter("Telerik.Framework.Utilities.GuidArrayConverter, Telerik.Framework")]
    public Guid[] PageIDs
    {
        get
        {
            object obj = this.ViewState["PageIDs"];
            if (obj != null)
                return (Guid[])obj;
            return new Guid[0];
             
        }
        set
        {
            this.ViewState["PageIDs"] = value;
        }
    }

I will override CreateChildControls() where I will dynamically create a RadMenu control and List of all selected pages. Then, I will bind the menu to this list similar to the way that is used in the custom selector to populate the RadTreeView control.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI.WebControls;
using Telerik.Cms.Web.UI;
using System.ComponentModel;
using Telerik.Web.UI;
using Telerik.Cms;
 
/// <summary>
/// Summary description for DynamicMenuBuilder
/// </summary>
public class DynamicMenuBuilder : CompositeControl
{
    public DynamicMenuBuilder()
    {
 
    }
 
    protected override void CreateChildControls()
    {
        base.CreateChildControls();
        RadMenu menu = new RadMenu();
        var Manager = new CmsManager();
        List<ICmsPage> selectedPages = new List<ICmsPage>();
 
        foreach (Guid g in PageIDs)
        {
            ICmsPage p = Manager.GetPage(g, false) as ICmsPage;
            if (p != null)
            {
                selectedPages.Add(p);
            }
        }
        menu.DataSource = selectedPages;
        menu.DataTextField = "MenuName";
        menu.DataFieldParentID = "ParentID";
        menu.DataFieldID = "ID";
        menu.DataNavigateUrlField = "StaticUrl";
        menu.DataBind();
        Controls.Add(menu);
    }
 
 
    [WebEditor("DynamicMenuBuilderWebUITypeEditor, App_Code")]
    [TypeConverter("Telerik.Framework.Utilities.GuidArrayConverter, Telerik.Framework")]
    public Guid[] PageIDs
    {
        get
        {
            object obj = this.ViewState["PageIDs"];
            if (obj != null)
                return (Guid[])obj;
            return new Guid[0];
             
        }
        set
        {
            this.ViewState["PageIDs"] = value;
        }
    }
}

25 comments

Leave a comment
  1. KingKong Feb 15, 2010
    Ivan, thank you for wonderful blog post. Using this selector I can now create custom navigation and easily choose which pages to show. It same me a lot of time trying to figure it out by myself.
  2. Romi Feb 19, 2010
    Kudos Ivan,
    Always more than expected ! It's possible to use as source for RadSitemap?. I have some items in my wish list if you like, one module using OpenAccess, and docks using v3+. Thanks, Romi.
  3. Mealworms Aug 08, 2010
    There are many cases where you want to have two level navigation or several navigational  menus. Each time you will have to do some coding over the menu so that it will start showing the appropriate items/nodes.
  4. sathi Dec 17, 2010
    I will bind the control to a list containing all pages by using the CmsManager.GetPages() method. Then I will return the ID
    Dog Boots
  5. AAAAAA May 14, 2011
    Hi
  6. readf Jun 19, 2012
    Each time you will have to do some coding over the menu so that it will start showing the appropriate items/nodes.<a href="http://www.bestbusinesslogodesignn.com/">business logo design</a>
  7. Miami Printing Oct 26, 2012
    These codes will help me improve my site. I only hope it will work on my end. :)
  8. Russian Shawls Oct 31, 2012
    I had so many questions on this topic, but your generous helped me to find answers for almost all of them. Thanks for sharing a nice information
  9. communication expert Nov 09, 2012
    Sitemenu Builder? I guess I can also make something like that for my own websites. I have to also make deal with it and thanks a lot for all the help. This is all what i really wanted.
  10. beef jerky Nov 15, 2012
    Having a website that looks nice is only part of the internet marketing package.
    Indeed it was an awesome post. It endows me with worthwhile information that
    definitely increases my awareness on this particular subject. For the person
    posted this editorial for the benefits of the general public thank you for
    sharing.
  11. informationonline.com Nov 20, 2012
    I am not really a web developer that is why I am not really an expert in creating websites, and etc... so right now I am looking for more information about it, search some resources to be used because I want to learn and I want to change my career.
  12. English speaking Dec 01, 2012
    This blog contains a lot of informative data and news which i first
    time read from here. Thanks for writing about this important topic.

     
  13. paracord bracelet Dec 13, 2012
    This post is truly inspiring. I like your post and everything you share with us is current and very informative,
  14. pmi-acp certification Jan 02, 2013

    I've been looking for this for a couple of an hour and I am so glad that you have shared this, thanks it really helps me.

  15. pmp flash cards Jan 02, 2013

    I've copied all the programming text here but when I am trying to save it, I just found some errors, I don't know where is it, I cannot trace it back.

  16. tefl certification online Jan 04, 2013
    I also encountered error when I paste this code, lacking comma, I cannot trace it back where part of the code that the comma is missing.
  17. online teaching jobs Jan 04, 2013
    Please consider in copying again the code and paste it again, let see if you encounter the same problem.
  18. best diet to be healthy Jan 23, 2013
    What kind of menu builder would that be? Is it something that we should be count on? or is it a user friendly or something? can you tell us more?
  19. test fixtures Feb 01, 2013

    What does that site menu builder mean? Does it really mean a lot to you? i know for sure things will be so alright and awesome if I am going to learn from it.

  20. Dentist South Jordan Feb 13, 2013

    "This post will show you how to create custom navigation menu for your website, where you can specify which pages you want to see and which not. "

    - This is how I would just always wanted to do and I am sure things would really go on that way.

  21. online pdu Feb 20, 2013
    It is fantastic blog providing you with us something to laugh. I find myself really fresh after every post for you personally. Keep providing us such posts. Thanks for this.
  22. free blogs Feb 28, 2013
    This article has some great and useful information about this subject.
    Thank you for sharing it in an easy to read and understandable format.
    Thanks for sharing this great information.
  23. Uchenna Jun 26, 2013
    Looks like a well drawn out method of accomplishing something that I've never really seen as being anything but complicated.
  24. Uchenna Jun 26, 2013
    Looks like a well drawn out method of accomplishing something that I've never really seen as being anything but complicated.
  25. Sophie Jul 19, 2013
    I have been looking for this for my website. Thanks.

    Leave a comment