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

Forums / Developing with Sitefinity / Binding sitemap data to RadPanelbar programmatically via XMLDataSource

Binding sitemap data to RadPanelbar programmatically via XMLDataSource

5 posts, 0 answered
  1. Dan
    Dan avatar
    14 posts
    Registered:
    30 May 2008
    27 May 2011
    Link to this post

    I'm trying to populate a RadPanelBar programmatically from an XmlDataSource defined in my code (i.e. not from an actual XML file), that copies nodes over from a SiteMapDataSource. I'm doing this because my site is extremely large (tens of thousands of pages), and we're getting major performance hits when trying to populate the RadPanelBar straight from the site map. Here's the ASP.NET code:

    <asp:SiteMapDataSource ID="SiteMapDataSource1" runat="server" StartingNodeOffset="1" StartFromCurrentNode="false" ShowStartingNode="false"/>
    <telerik:RadPanelBar ID="RadPanelbar1" OnItemDataBound="RadPanelbar1_ItemDataBound" EnableViewState="false" runat="server"></telerik:RadPanelBar>

    And here's the C# code as it is:

    SiteMapNode root = SiteMapDataSource1.Provider.CurrentNode;
    XmlDataSource flatmap = new XmlDataSource();
    flatmap.ID = "FlatMapXmlSource01";
    XmlDocument flatmapdoc = new XmlDocument();
    XmlNode flatroot = flatmapdoc.CreateNode(XmlNodeType.Element, "Panelbar",
        string.Empty);
    XmlNode frTitle = flatmapdoc.CreateNode(XmlNodeType.Attribute, "Text",
        string.Empty);
    frTitle.InnerText = root.Title.ToString();
    flatroot.Attributes.SetNamedItem(frTitle);
    flatmapdoc.AppendChild(flatroot);
      
    foreach (SiteMapNode child in root.ChildNodes) {
        XmlNode newchild = flatmapdoc.CreateNode(XmlNodeType.Element, "Item",
            string.Empty);
        XmlNode ncTitle = flatmapdoc.CreateNode(XmlNodeType.Attribute, "Text",
            string.Empty);
        ncTitle.InnerText = child.Title.ToString();
        newchild.Attributes.SetNamedItem(ncTitle);
        flatroot.AppendChild(newchild);
    }
      
    flatmap.Data = flatmapdoc.InnerXml;
    flatmap.DataBind();
    RadPanelbar1.DataSource = flatmap;
    //RadPanelbar1.DataTextField = "Text";
    //RadPanelbar1.DataNavigateUrlField = "Url";
    //RadPanelbar1.DataValueField = "Text";
    RadPanelbar1.DataBind();

    My first question is: The RadPanelBar isn't loading the items properly. It loads the item hierarchy, but the names of the items are all "Panelbar" and "Item", rather than the actual page names. I tried to fix this by setting the DataTextField and related values (commented out above), but this gave me the error "Object of type System.Web.UI.WebControls.XmlHierarchyData does not contain a property with the name 'Text'" (same error for 'Url'). Is there something else missing from my code to make the RadPanelBar/XmlDataSource binding work, or is this just some undocumented RadPanelBar quirk?

    My second question is: is this even a good idea? What I'm trying to do is to optimize the RadPanelBar's performance by traversing the site map and only binding those nodes that are absolutely necessary to bind. When our website was smaller, this was never a problem, although we did notice some slowness. Nowadays, when I try to load our previous panelbar control onto a new template (we're using Sitefinity 3.7), it takes so long that the page hits a timeout before it has time to load, and so I'm not even able to save the modified template. Any suggestions as to whether what I'm trying to do here (manual traversal of the site map via XML instead of relying on a SiteMapDataSource to bind itself) would work, or whether I should try a different approach?

  2. Ivan Dimitrov
    Ivan Dimitrov avatar
    16072 posts
    Registered:
    25 Nov 2016
    02 Jun 2011
    Link to this post
    Hi Dan,

    You are trying to populate the control with data from HierarchicalDataBoundControl Class which does not contain Title propery. You can create a helper class that expose this property

    sample

      public class BuildDataSource
        {
     
            public BuildDataSource(string _title)
            {
                Title = _title;
       
            }
     
            public string Title
            {
                get;
                set;
            }
    }

    You can also use new RadPanelItem and populate the controls hierarchically load on demand.  When you click on a root item, you will call BuildDataSource and populate it only with rootitem.items. The same applies if you click on any other child item.

    Please check this demo

    http://demos.telerik.com/aspnet-ajax/panelbar/examples/populatingwithdata/hierarchicalbinding/defaultcs.aspx

    All the best,
    Ivan Dimitrov
    the Telerik team
    Do you want to have your say in the Sitefinity development roadmap? Do you want to know when a feature you requested is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
  3. Dan
    Dan avatar
    14 posts
    Registered:
    30 May 2008
    08 Jun 2011
    Link to this post
    Hi Ivan,

    I don't really understand what you mean. I used "Title" in lines like

    frTitle.InnerText = root.Title.ToString();

    because root refers to the SiteMapNode objects contained in the SiteMapDataSource Provider, and SiteMapNode objects have Title properties. If you're referring to frTitle, that's just the name of an XmlNode; I'm not putting data into frTitle.Title, but frTitle.InnerText (since I'm using an XmlDataSource to populate the RadPanelBar). Maybe I'm misunderstanding what you're trying to say, though.

    Also, I looked into the example URL you posted, but it didn't seem very helpful at all since it doesn't deal with XmlDataSource—the example only shows DataSets and IEnumerables.
  4. Ivan Dimitrov
    Ivan Dimitrov avatar
    16072 posts
    Registered:
    25 Nov 2016
    09 Jun 2011
    Link to this post
    Hi Dan,

    You object is not SiteMapNode. It is XmlHierarchyData. According to the MSDN there is not Title property. You need a helper class to make the conversation.

    Kind regards,
    Ivan Dimitrov
    the Telerik team
    Do you want to have your say in the Sitefinity development roadmap? Do you want to know when a feature you requested is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
  5. Dan
    Dan avatar
    14 posts
    Registered:
    30 May 2008
    09 Jun 2011
    Link to this post
    Hi Ivan,

    I still don't understand what you're trying to explain. I suspect we may be thinking about two different things. Allow me to ask for some clarification—which object is XmlHierarchyData? root? frTitle? flatmap? flatmapdoc? newchild? I also don't understand how the "Title" property is relevant when I was trying to set DataTextField and DataNavigateUrlField to "Text" and "Url", and not "Title". "Title" is only used in referring to objects like root, a SiteMapNode, which clearly has a Title property, which I convert to a string to feed to an XmlNode's InnerText property.

    By the way, after making some minor changes to my code, I'm now finding that it works, somewhat—although I don't see how the changes I've made may have fixed the problem. I'm seeing the correct names appearing on the PanelBar items now (i.e. "Testing Folder", etc). Here's the code that's changed since the above version:

    foreach (SiteMapNode child in root.ChildNodes)
    {
        XmlNode newchild = flatmapdoc.CreateNode(XmlNodeType.Element, "Item", string.Empty);
        XmlNode ncTitle = flatmapdoc.CreateNode(XmlNodeType.Attribute, "Text", string.Empty);
        ncTitle.InnerText = child.Title.ToString();
        XmlNode ncURL = flatmapdoc.CreateNode(XmlNodeType.Attribute, "NavigateUrl", string.Empty);
        ncURL.InnerText = child.Url.ToString();
        newchild.Attributes.SetNamedItem(ncTitle);
        newchild.Attributes.SetNamedItem(ncURL);
        flatroot.AppendChild(newchild);
    }
    flatmap.Data = flatmapdoc.InnerXml;
    flatmap.DataBind();
    RadPanelbar1.DataSource = flatmap;
    RadPanelbar1.DataTextField = "Text";
    //RadPanelbar1.DataNavigateUrlField = "NavigateUrl";
    RadPanelbar1.DataValueField = "Text";
    RadPanelbar1.DataBind();

    I don't know why it works now, but the above code works, except that it's not adding links to my PanelBar items. When I uncomment the line about RadPanelbar1.DataNavigateUrlField, it gives me the same error as before ("Object of type System.Web.UI.WebControls.XmlHierarchyData does not contain a property with the name 'NavigateUrl'").

    Sorry for all these misunderstandings. I'm desperately trying to understand what's going wrong! If it would help, I can post both the .ascx and .ascx.cs files so that you can get the entire picture of what's going on in this control.
Register for webinar
5 posts, 0 answered