+1-888-365-2779
Try Now
More in this section

Forums / General Discussions / Custom RadMenu not showing items

Custom RadMenu not showing items

4 posts, 0 answered
  1. Jason
    Jason avatar
    23 posts
    Registered:
    17 Jun 2009
    01 Nov 2009
    Link to this post
    Hi,

    I love using your products and now suggest sitefinity CMS to all my clients with existing clients keen to make the switch.

    I am still relatively new to ASP websites but I find sitefinity is powerful yet easy to navigate and customize.

    With that said, i am having an issue with a custom menu.  I have a site that requires that the menu items change depending on what parent item is current.  I did manage to achieve this using the starting url IF statement which worked as expected.  I would like to know if there is a way to get the starting url to automatically look for the parent and set it's value to that rather than coding the parent.  Below is the code for this function:

    [

    WebEditor("Telerik.Cms.Web.UI.UrlEditorWrapper, Telerik.Cms")]

     

    [

    Browsable(true)]

     

    [

    Category("Navigation")]

     

     

    public string StartingNodeUrl

     

    {

     

        get

     

        {

     

            if (SiteMapDataSource1.StartingNodeUrl == string.Empty)

     

     

                return "~/Downloads.aspx";

     

     

            return this.SiteMapDataSource1.StartingNodeUrl;

     

        }

     

        set

     

        {

     

        this.SiteMapDataSource1.StartingNodeUrl = value;

     

        }

    }

    The other problem I am having is when i make this a custom control and move the ascx and cs files to their own directory Custom/Menu/Downloads.ascx it displays a blank nothing when the control is added to the page.  I am obviously missing  link to other files somewhere.  The CSS is through a file in the themes folder.

    You help is much appreciated.

    Thank you for your time.

    Jason

  2. Ivan Dimitrov
    Ivan Dimitrov avatar
    16072 posts
    Registered:
    25 Nov 2016
    01 Nov 2009
    Link to this post
    Hi Jason,

    For the first issue :The code below will get all root items of your RadMenu control

    foreach(RadMenuItem item in RadMenu1.Items)
    if (item.Parent == null)
    {
        // so something
    }

    For the second one: Make sure that the control is bound to your SiteMapDataSource. You can add the following skin file to your theme which will set the styles to your RadMenu automatically when you select this theme.

    <%@ Register TagPrefix="telerik" Assembly="Telerik.Web.UI" Namespace="Telerik.Web.UI" %>
    <telerik:RadMenu   
        runat="server"
        Skin="YOUR CUSTOM SKIN HERE" EnableEmbeddedSkins="false"
        >
    </telerik:RadMenu>

    Let us know how it goes.

    Kind regards,
    Ivan Dimitrov
    the Telerik team

    Instantly find answers to your questions on the new Telerik Support Portal.
    Watch a video on how to optimize your support resource searches and check out more tips on the blogs.
  3. Jason
    Jason avatar
    23 posts
    Registered:
    17 Jun 2009
    02 Nov 2009
    Link to this post
    Thank you for your reply.  Your answers have helped a lot however I am still unable to bind to the SitemapDataSource.  I am still new to sitefinity and especially new to creating custom controls.  I grabbed the code from the navigation35 directory and copied it to my own custom folder.  Then linked this in web.config file.  Here is the ascx and cs code for the control.  Now i have to figure out how to populate this with the pages that get added to the site. 

    <%@ Control Language="C#" AutoEventWireup="true" CodeFile="Downloads.ascx.cs" Inherits="Custom_Menu_Downloads" %> 
    <%@ Register TagPrefix="telerik" Assembly="Telerik.Web.UI" Namespace="Telerik.Web.UI" %> 
     
    <asp:SiteMapDataSource ID="SiteMapDataSource1" runat="server" ShowStartingNode="false" /> 
    <telerik:RadMenu ID="RadMenu1" runat="server" DataSourceID="SitemapDataSource1" OnItemDataBound="RadMenu1_ItemDataBound" EnableEmbeddedSkins="False" Skin="AEG">  
    </telerik:RadMenu> 
    *.ascx file

    using System;  
    using System.Data;  
    using System.Configuration;  
    using System.Collections;  
    using System.Web;  
    using System.Web.Security;  
    using System.Web.UI;  
    using System.Web.UI.WebControls;  
    using System.Web.UI.WebControls.WebParts;  
    using System.Web.UI.HtmlControls;  
    using System.ComponentModel;  
    using System.Drawing;  
     
    using Telerik;  
    using Telerik.Cms;  
    using Telerik.Cms.Web;  
    using Telerik.Web.UI;  
    using Telerik.Caching;  
    using Telerik.Cms.Web.UI;  
     
    /// <summary> 
    /// Represents a wrapper for <strong>RadMenu</strong> and  
    /// <strong>SitemapDataSource</strong>. Derives from  
    /// <href="http://msdn2.microsoft.com/en-us/library/system.web.ui.usercontrol.aspx">System.Web.UI.UserControl</a>.  
    /// </summary> 
    /// <remarks> 
    ///     <para>The control has the functionality of <strong>RadMenu</strong>, however it is  
    ///     specifically configured for representing sitemap data. It exposes the contained  
    ///     <strong>RadMenu</strong> as a property, whose own properties can be edited from the  
    ///     visual property editor of Sitefinity.</para> 
    ///     <para>The control also can be configured to display only several levels from the  
    ///     sitemap hierarchy, using the <strong>LastExpandLevel</strong> property.</para> 
    ///     <para>Menu items corresponding to group pages can be set to redirect to the first  
    ///     child page (default) or just expand to show the children and do not redirect, using  
    ///     the <strong>HideUrlForGroupPages</strong> property.</para> 
    /// </remarks> 
    [DefaultProperty("StartingNodeOffset")]  
     
     
     
    public partial class Custom_Menu_Downloads : System.Web.UI.UserControl, ICacheableObject  
    {  
          
     
        protected void Page_Load(object sender, EventArgs e)  
        {  
     
        }  
     
        /// <summary> 
        /// Overriden. Renders the control content.  
        /// </summary> 
        /// <param name="writer"></param> 
        protected override void Render(HtmlTextWriter writer)  
        {  
            // Checks if this is called by the Search Indexer and does not render anything if so.  
            // Navigation controls are present in every page and should NOT be indexed multiple times.  
              
              
            //if (!CmsContext.IsRequestCrawler)  
            //    base.Render(writer);  
        }  
     
        #region Data Fields  
     
        private bool hideUrlForGroupPages = false;  
        private string selectedItemCssClass = "selectedItem";  
     
        #endregion  
     
        #region Properties  
     
     
        /// <summary> 
        /// Gets or sets the value that indicates how many levels deep the menu will expand.  
        /// 0 means that all levels will be expanded.  
        /// </summary> 
        /// <value>The default is 0.</value> 
        /// <remarks> 
        /// In some situations page navigation may be implemented only for selected levels  
        /// from the sitemap hierarchy. This property sets the value indicating which is the last  
        /// level that should be expanded.  
        /// </remarks> 
        /// <example> 
        ///     <para><font style="BACKGROUND-COLOR: #ffffff">If you want to limit the level to  
        ///     which submenus are expanded you can use this property to achieve it. For this  
        ///     example we have created a site with three pages - FirstPage, ChildPage1 and  
        ///     ChildPage2. ChildPage2 is subordinate to ChildPage1, which in turn is subordinate  
        ///     to FirstPage. The hierarchy looks like this:</font></para>  
        ///     <para> 
        ///         <img src="file:///C:/Documents%20and%20Settings/ingilizov/Desktop/MenuExamples/MenuExample2_img1.JPG"/>  
        ///     </para> 
        ///     <para>The default value for property LastExpandLevel is 0, meaning that all levels  
        ///     of the menu will be expanded:</para> 
        ///     <para> 
        ///         <img src="file:///C:/Documents%20and%20Settings/ingilizov/Desktop/MenuExamples/MenuExample2_img2.JPG"/>  
        ///     </para> 
        ///     <para>Let's say that we want to display only 1st and 2nd level items in the menu.  
        ///     (We may want to provide 3rd level item navigation in a panelbar, individual for  
        ///     every page.). To achieve this, we set the LastExpandLevel property to 2, and then  
        ///     the 3rd level is not expanded.</para> 
        ///     <para> 
        ///         <img src="file:///C:/Documents%20and%20Settings/ingilizov/Desktop/MenuExamples/MenuExample2_img3.JPG"/>  
        ///         <img src="file:///C:/Documents%20and%20Settings/ingilizov/Desktop/MenuExamples/MenuExample2_img4.JPG"/>  
        ///     </para> 
        /// </example> 
        [Browsable(true)]  
        [Category("Behavior")]  
        public int LastExpandLevel  
        {  
            get  
            {  
                if (this.RadMenu1.MaxDataBindDepth < 0)  
                    return 0;  
                return this.RadMenu1.MaxDataBindDepth;  
            }  
            set  
            {  
                if (value == 0)  
                    this.RadMenu1.MaxDataBindDepth = -1;  
                else  
                    this.RadMenu1.MaxDataBindDepth = value;  
            }  
        }  
     
        /// <summary> 
        /// (Exposed from contained RadMenu.) Gets or sets a value indicating the timeout  
        /// after which a menu item starts to open.  
        /// </summary> 
        /// <value> 
        /// An integer specifying the timeout measured in milliseconds. The default value is  
        /// 0 which means that menu items open immediately.  
        /// </value> 
        /// <remarks><para>Use the <strong>ExpandDelay</strong> property to delay item opening.</para></remarks>  
        [Browsable(true)]  
        [Category("Behavior")]  
        public int ExpandDelay  
        {  
            get  
            {  
                return this.RadMenu1.ExpandDelay;  
            }  
            set  
            {  
                this.RadMenu1.ExpandDelay = value;  
            }  
        }  
     
        /// <summary> 
        /// (Exposed from contained RadMenu.) Gets or sets a value indicating whether root  
        /// items should open on mouse click.  
        /// </summary> 
        /// <value> 
        ///     <strong>True</strong> if the root items open on mouse click; otherwise  
        /// <strong>false</strong>. The default value is <strong>false</strong>.  
        /// </value> 
        /// <remarks> 
        /// Use the <strong>ClickToOpen</strong> property to customize the way root menu  
        /// items are opened. By default menu items are opened on mouse hovering.  
        /// </remarks> 
        [Browsable(true)]  
        [Category("Behavior")]  
        public bool ClickToOpen  
        {  
            get  
            {  
                return this.RadMenu1.ClickToOpen;  
            }  
            set  
            {  
                this.RadMenu1.ClickToOpen = value;  
            }  
        }  
     
        /// <summary> 
        /// Gets or sets a value indicating whether the RadMenuItems representing group pages  
        /// should redirect to other pages or only expand to show their child pages.  
        /// </summary> 
        /// <remarks> 
        /// By default every group page in Sitefinity redirects to its first child page when  
        /// accessed. This property enables overriding this behaviour by checking the page type for  
        /// every node in the RadMenu and disabling redirection if the page is a group page. If  
        /// redirection is disabled, the node only expands to show its children.  
        /// </remarks> 
        /// <example> 
        ///     <para><font style="BACKGROUND-COLOR: #ffffff">Note: This example makes sense only  
        ///     if the ClickToOpen property for the control is set to true. Otherwise, the menus  
        ///     are expanded on the client and the HideUrlForGroupPages property is not  
        ///     applied.</font></para>  
        ///     <para><font style="BACKGROUND-COLOR: #ffffff">This example shows how the  
        ///     HideUrlForGroupPages property is used. There are four pages created in Sitefinity -  
        ///     FirstPage, SecondPage, ChildPage1 and ChildPage2. ChildPage1 is a subpage of  
        ///     FirstPage. ChildPage2 is a subpage of SecondPage. All pages are normal, except for  
        ///     SecondPage, which is a group page. Here is how the hierarchy looks:</font></para>  
        ///     <para> 
        ///         <img src="file:///C:/Documents%20and%20Settings/ingilizov/Desktop/MenuExamples/MenuExample1_img1.JPG"/>  
        ///     </para> 
        ///     <para>By default the HideurlForGroupPages is set to <strong>false</strong>. When we  
        ///     expand the node for SecondPage, we are redirected to ChildPage2.</para> 
        ///     <para> 
        ///         <img src="file:///C:/Documents%20and%20Settings/ingilizov/Desktop/MenuExamples/MenuExample1_img2.JPG"/>  
        ///         <img src="file:///C:/Documents%20and%20Settings/ingilizov/Desktop/MenuExamples/MenuExample1_img3.JPG"/>  
        ///     </para> 
        ///     <para>Now, if we set the value of the property to true, the Menu is expanded and we  
        ///     are not redirected.</para> 
        ///     <para> 
        ///         <img src="file:///C:/Documents%20and%20Settings/ingilizov/Desktop/MenuExamples/MenuExample1_img4.JPG"/>  
        ///         <img src="file:///C:/Documents%20and%20Settings/ingilizov/Desktop/MenuExamples/MenuExample1_img5.JPG"/>  
        ///     </para> 
        /// </example> 
        [Browsable(true)]  
        [Category("Behavior")]  
        [DefaultValue(false)]  
        public bool HideUrlForGroupPages  
        {  
            get  
            {  
                return this.hideUrlForGroupPages;  
            }  
            set  
            {  
                this.hideUrlForGroupPages = value;  
            }  
        }  
     
        /// <summary> 
        /// (Exposed from contained RadMenu.) Gets or sets the Cascading Style Sheet (CSS)  
        /// class rendered by selected items of the Web server control on the client.  
        /// </summary> 
        [Browsable(true)]  
        [Category("Appearance")]  
        public string SelectedItemCssClass  
        {  
            get  
            {  
                return this.selectedItemCssClass;  
            }  
            set  
            {  
                this.selectedItemCssClass = value;  
            }  
        }  
     
        /// <summary> 
        /// (Exposed from contained RadMenu.) Gets or sets the Cascading Style Sheet (CSS)  
        /// class rendered by the Web server control on the client.  
        /// </summary> 
        /// <remarks> 
        /// (Inherited from  
        /// <onclick="javascript:navigateToHelp2Keyword('frlrfSystemWebUIWebControlsWebControlClassTopic','System.Web.UI.WebControls.WebControl')" href="#">System.Web.UI.WebControls.WebControl</a>)  
        /// </remarks> 
        [Browsable(true)]  
        [Category("Appearance")]  
        public string CssClass  
        {  
            get  
            {  
                return this.RadMenu1.CssClass;  
            }  
            set  
            {  
                this.RadMenu1.CssClass = value;  
            }  
        }  
     
        /// <summary> 
        /// Represents a reference to the wrapped RadMenu control. Can be used to access  
        /// properties which are not directly available in the user control.  
        /// </summary> 
        [Browsable(true)]  
        public RadMenu Menu  
        {  
            get  
            {  
                return this.RadMenu1;  
            }  
            set  
            {  
                this.RadMenu1 = value;  
            }  
        }  
     
        /// <summary> 
        /// (Exposed from contained SitemapDataSource.) Gets or sets a positive or negative  
        /// integer offset from the starting node that determines the root hierarchy that is  
        /// exposed by the data source control.  
        /// </summary> 
        /// <value> 
        /// The default is 0, which indicates that the root hierarchy exposed by the  
        /// SiteMapDataSource is the same as the starting node.  
        /// </value> 
        /// <example> 
        /// </example> 
        /// <remarks> 
        ///     <para>If the <b>StartingNodeOffset</b> property is set to a value other than 0, it  
        ///     affects the starting node and with it the site map data hierarchy that is exposed  
        ///     by the <b>SiteMapDataSource</b> control. The negative or positive integer value of  
        ///     the <b>StartingNodeOffset</b> identifies the number of levels up or down the site  
        ///     map hierarchy from the starting node that is identified by the  
        ///     <strong>StartFromCurrentNode</strong> and StartingNodeUrl properties to offset the  
        ///     starting node of the subtree that is exposed by data source control.</para> 
        ///     <para>If the identified starting node is the node that represents the currently  
        ///     requested page, the <b>StartingNodeOffset</b> is ignored.</para> 
        ///     <para>If the <b>StartingNodeOffset</b> property is set to a negative number  
        ///     -<i>n</i>, the starting node of the subtree that is exposed by the data source  
        ///     control is the ancestor node <i>n</i> hierarchical levels above the identified  
        ///     starting node. If the value <i>n</i> is greater than the number of ancestor levels  
        ///     in the hierarchical tree, the starting node of the subtree is the root node of the  
        ///     site map hierarchy.</para> 
        /// </remarks> 
        [Browsable(true)]  
        [Category("Navigation")]  
        public int StartingNodeOffset  
        {  
            get  
            {  
                return this.SiteMapDataSource1.StartingNodeOffset;  
            }  
            set  
            {  
                this.SiteMapDataSource1.StartingNodeOffset = value;  
            }  
        }  
          
        /// <summary> 
        /// (Exposed from contained SitemapDataSource.) Gets or sets an URL  
        /// of starting node that determines the root hierarchy that is  
        /// exposed by the data source control.  
        /// </summary> 
        ///   
        [WebEditor("Telerik.Cms.Web.UI.UrlEditorWrapper, Telerik.Cms")]  
        [Browsable(true)]  
        [Category("Navigation")]  
        public string StartingNodeUrl  
        {  
            get  
            {  
                if (SiteMapDataSource1.StartingNodeUrl == string.Empty)  
                    return "~/Downloads.aspx";  
                return this.SiteMapDataSource1.StartingNodeUrl;  
            }  
            set  
            {  
                this.SiteMapDataSource1.StartingNodeUrl = value;  
            }  
        }   
     
        /// <summary> 
        /// (Exposed from contained SitemapDataSource.) Gets or sets a value indicating  
        /// whether the site map node tree is retrieved using the node that represents the current  
        /// page.  
        /// </summary> 
        /// <value> 
        ///     <strong>true</strong> if the node tree is retrieved relative to the current page;  
        /// otherwise, <b>false</b>. The default is <b>false</b>.  
        /// </value> 
        /// <remarks> 
        /// The <b>StartFromCurrentNode</b> property is evaluated during calls to the GetView  
        /// and the GetHierarchicalView methods to help determine which site map node to use as a  
        /// starting point to build the node tree. The <b>StartFromCurrentNode</b> and  
        /// StartingNodeUrl properties are mutually exclusive — if you set the  
        /// <b>StartingNodeUrl</b> property, ensure that the <b>StartFromCurrentNode</b> property  
        /// is <b>false</b>.  
        /// </remarks> 
        [Browsable(true)]  
        [Category("Navigation")]  
        public bool StartFromCurrentNode  
        {  
            get  
            {  
                return this.SiteMapDataSource1.StartFromCurrentNode;  
            }  
            set  
            {  
                this.SiteMapDataSource1.StartFromCurrentNode = false;  
            }  
        }  
     
        /// <summary> 
        /// (Exposed from contained SitemapDataSource.) Gets or sets a value indicating  
        /// whether the starting node is retrieved and displayed.  
        /// </summary> 
        /// <value> 
        ///     <strong>true</strong> if the starting node is displayed; otherwise, <b>false</b>.  
        /// The default is <b>false</b>.  
        /// </value> 
        /// <remarks> 
        /// The <b>ShowStartingNode</b> property is evaluated during calls to the GetView and  
        /// GetHierarchicalView methods, when the node tree that is returned by these methods is  
        /// populated.  
        /// </remarks> 
        [Browsable(true)]  
        [Category("Navigation")]  
        public bool ShowStartingNode  
        {  
            get  
            {  
                return this.SiteMapDataSource1.ShowStartingNode;  
            }  
            set  
            {  
                this.SiteMapDataSource1.ShowStartingNode = false;  
            }  
        }  
     
        /// <summary>(Exposed from contained RadMenu.)</summary> 
        [Browsable(true)]  
        [Category("Appearance")]  
        public string SkinID  
        {  
            get  
            {  
                return this.RadMenu1.SkinID;  
            }  
            set  
            {  
                this.RadMenu1.SkinID = value;  
            }  
        }  
     
        /// <summary>(Exposed from contained RadMenu.) Gets or sets the skin used by RadMenu.</summary> 
        /// <value> 
        /// A  
        /// <onclick="javascript:navigateToHelp2Keyword('frlrfSystemStringClassTopic','System.String')" href="#">String</a> specifying the skin. The default value is empty string  
        ///    ("").  
        /// </value> 
        /// <remarks>If the value is empty string ("") no skin is used.</remarks> 
        [Browsable(true)]  
        [Category("Appearance")]  
        public string Skin  
        {  
            get  
            {  
                return this.RadMenu1.Skin;  
            }  
            set  
            {  
                this.RadMenu1.Skin = value;  
            }  
        }  
     
        #endregion  
     
        #region Methods  
     
        /// <summary> 
        /// A handler for the <strong>RadMenu</strong> ItemDataBound event. Performs hiding  
        /// of URLs for group pages, if the <strong>HideUrlForGroupPages</strong> property is  
        /// <strong>true</strong>.  
        /// </summary> 
        /// <remarks> 
        /// The event handler is used to enable the feature of hiding the url for a group  
        /// page MenuItem. The type of the page corresponding to the current node is checked and if  
        /// it is a group page, the url for the CmsSiteMapNode is set to an empty string.  
        /// </remarks> 
        /// <param name="sender">The object that caused the event.</param> 
        /// <param name="e">  
        /// An instance of the RadMenuEventArgs class containing information about the  
        /// event.  
        /// </param> 
        public void RadMenu1_ItemDataBound(object sender, RadMenuEventArgs e)  
        {  
            if (this.hideUrlForGroupPages)  
            {  
                CmsSiteMapNode node = e.Item.DataItem as CmsSiteMapNode;  
                if (node != null)  
                {  
                    // save the PageID in the attributes of the menu item  
                    e.Item.Attributes.Add("PageID", node.Key);  
     
                    if (node.PageType == CmsPageType.Group)  
                    {  
                        e.Item.NavigateUrl = "";  
                    }  
                }  
            }  
        }  
     
        #endregion  
     
        #region ICacheableObject Members  
     
        public System.Web.Caching.CacheDependency[] GetDependencies()  
        {  
            CmsSiteMapProvider provider = null;  
            if (!String.IsNullOrEmpty(this.SiteMapDataSource1.SiteMapProvider))  
                provider = SiteMap.Providers[this.SiteMapDataSource1.SiteMapProvider] as CmsSiteMapProvider;  
            else  
                provider = SiteMap.Provider as CmsSiteMapProvider;  
            if (provider != null)  
            {  
                return new System.Web.Caching.CacheDependency[]{ provider.CloneCacheDependency()};  
            }  
            return null;  
        }  
     
        #endregion  
    }  
     

    *.ascx.cs file

    The menu is added to the child pages and only diplays the child pages that are listed under the appropriate parent.  At this stage we add the starting node manually but this is getting to be a chore as the site now has a lot of pages.  I think i am close to solving this however your help would be appreciated in detailing how to get the menu to populate with the appropriate pages when dropped onto the page.

    Jason
  4. Ivan Dimitrov
    Ivan Dimitrov avatar
    16072 posts
    Registered:
    25 Nov 2016
    03 Nov 2009
    Link to this post
    Hi Jason,

    You can set StartFromCurrentNode property to true. By doing so the menu will bind only the child pages of your parent item where the menu has been dropped.

    Sincerely yours,
    Ivan Dimitrov
    the Telerik team

    Instantly find answers to your questions on the new Telerik Support Portal.
    Watch a video on how to optimize your support resource searches and check out more tips on the blogs.
Register for webinar
4 posts, 0 answered