More in this section

Forums / General Discussions / Custom Menu using Repeater

Custom Menu using Repeater

7 posts, 0 answered
  1. Dallas Beek
    Dallas Beek avatar
    10 posts
    Registered:
    19 May 2010
    13 Jan 2011
    Link to this post
    I have a custom control in which I am trying to render a menu using a repeater and a nested repeater.  When I run it something is happening as a result of the nested repeater and it's databinding.  I'm fairly sure the template is right as it was taken from an MSDN article.

    Error
    InvalidOperationException: Cannot convert from string.]
       Telerik.Sitefinity.Web.UI.Templates.Attribute..ctor(String name, String value, ObjectBuilder builder, PropertyDescriptorCollection properties) +1350
       Telerik.Sitefinity.Web.UI.Templates.TemplateParser.CreateObjectBuilder(HtmlChunk chunk) +414
       Telerik.Sitefinity.Web.UI.Templates.TemplateParser.ParseChunk(HtmlChunk chunk) +75
       Telerik.Sitefinity.Web.UI.Templates.TemplateParser.Parse() +187

    The Control
    public partial class CustomNavigationControl : SimpleView {
        
          protected override string LayoutTemplateName {
              get {
                  return CustomNavigationControl.layoutTemplateName;
              }
          }
          protected override void InitializeControls(Telerik.Sitefinity.Web.UI.GenericContainer container) {
            //  base.InitializeControls(container);
          }
          private const string layoutTemplateName = "JHFControls.Resources.Views.CustomNavigationControl.ascx";
      }

    The template
    <%@ Control Language="C#" %>
    <asp:Repeater runat="server" ID="menu" DataSourceID="SiteMapDataSource1">
        <HeaderTemplate>
            <ul id="topnav">
        </HeaderTemplate>
        <ItemTemplate>
            <li>
                <asp:HyperLink ID="HyperLink1" runat="server" NavigateUrl='<%# Eval("Url") %>'><%# Eval("Title") %></asp:HyperLink>
                <asp:Repeater ID="submenu" runat="server" DataSource='<%# ((SiteMapNode) Container.DataItem).ChildNodes %>'>
                    <HeaderTemplate>
                        <ul>
                    </HeaderTemplate>
                    <ItemTemplate>
                        <li>
                            <asp:HyperLink ID="HyperLink2" runat="server" NavigateUrl='<%# Eval("Url") %>'><%# Eval("Title") %></asp:HyperLink>
                        </li>
                    </ItemTemplate>
                    <FooterTemplate>
                        </ul>
                    </FooterTemplate>
                </asp:Repeater>
            </li>
        </ItemTemplate>
        <FooterTemplate>
            </ul>
        </FooterTemplate>
    </asp:Repeater>
    <asp:SiteMapDataSource ID="SiteMapDataSource1" runat="server" ShowStartingNode="false" ViewStateMode="Disabled" />

  2. Ivan Dimitrov
    Ivan Dimitrov avatar
    16072 posts
    Registered:
    12 Sep 2017
    13 Jan 2011
    Link to this post
    Hello Dallas,

    Remove the comment from base.InitializeControls(container)

    protected override void InitializeControls(Telerik.Sitefinity.Web.UI.GenericContainer container) {
            //  base.InitializeControls(container);
          }


    Kind regards,
    Ivan Dimitrov
    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
  3. Dallas Beek
    Dallas Beek avatar
    10 posts
    Registered:
    19 May 2010
    13 Jan 2011
    Link to this post

    Error 1 Cannot call an abstract base member:
    'Telerik.Sitefinity.Web.UI.SimpleView.InitializeControls(Telerik.Sitefinity.Web.UI.GenericContainer)'

     

  4. Ivan Dimitrov
    Ivan Dimitrov avatar
    16072 posts
    Registered:
    12 Sep 2017
    13 Jan 2011
    Link to this post
    Hi Dallas,

    OK, yes you should not call the base when you inherit from SimpleView. Have you set CustomNavigationControl.ascx Build Action as "Embed Resource"? Can you remove the code inside <ItemTemplate> from both the Repeaters to see whether the error will appear.

    Regards,
    Ivan Dimitrov
    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
  5. Dallas Beek
    Dallas Beek avatar
    10 posts
    Registered:
    19 May 2010
    13 Jan 2011
    Link to this post
    The control is an embedded resource.  The error occurs on the second binding.

    <asp:Repeater ID="submenu" runat="server" DataSource='<%# ((SiteMapNode) Container.DataItem).ChildNodes %>'> 

    If I change the datasource on the inside repeater to SiteMapDataSource1 it will work. 
  6. George
    George avatar
    28 posts
    Registered:
    24 Sep 2012
    19 Jan 2011
    Link to this post
    Hello Dallas Beek,

    Sitefinity uses its own parser for parsing embedded resources. Compared to the ASP.NET parser, this parser has limited capabilities for parsing C# code. In the case with your template code, the non-parsable expression is,

    <%# ((SiteMapNode) Container.DataItem).ChildNodes %>

    The shortest solution is remove this code from your .ascx file so it will look like,

    <%@ Control Language="C#" %>
    <asp:Repeater runat="server" ID="menu" DataSourceID="SiteMapDataSource1">
        <HeaderTemplate>
            <ul id="topnav">
        </HeaderTemplate>
        <ItemTemplate>
            <li>
                <asp:HyperLink ID="HyperLink1" runat="server" NavigateUrl='<%# Eval("Url") %>'><%# Eval("Title") %></asp:HyperLink>
                <asp:Repeater ID="submenu" runat="server">
                    <HeaderTemplate>
                        <ul>
                    </HeaderTemplate>
                    <ItemTemplate>
                        <li>
                            <asp:HyperLink ID="HyperLink2" runat="server" NavigateUrl='<%# Eval("Url") %>'><%# Eval("Title") %></asp:HyperLink>
                        </li>
                    </ItemTemplate>
                    <FooterTemplate>
                        </ul>
                    </FooterTemplate>
                </asp:Repeater>
            </li>
        </ItemTemplate>
        <FooterTemplate>
            </ul>
        </FooterTemplate>
    </asp:Repeater>
    <asp:SiteMapDataSource ID="SiteMapDataSource1" runat="server" ShowStartingNode="false" ViewStateMode="Disabled" />

    and then to move the place the same logic to the CustomNavigationControl.cs file, so it  may look like

    public partial class CustomNavigationControl : SimpleView
    {
     
        protected override string LayoutTemplateName
        {
            get
            {
                return CustomNavigationControl.layoutTemplateName;
            }
        }
        protected override void InitializeControls(Telerik.Sitefinity.Web.UI.GenericContainer container)
        {
            container.GetControl<Repeater>("menu", true).ItemDataBound += new RepeaterItemEventHandler(CustomNavigationControl_ItemDataBound);
     
            //  base.InitializeControls(container);
        }
     
        void CustomNavigationControl_DataBinding(object sender, EventArgs e)
        {
             
        }
     
        void CustomNavigationControl_ItemDataBound(object sender, RepeaterItemEventArgs e)
        {
            if (e.Item.ItemType.ToString() == "Item")
            {
                var secondRepeater = e.Item.FindControl("submenu") as Repeater;
                secondRepeater.DataSource = ((SiteMapNode)e.Item.DataItem).ChildNodes;
                secondRepeater.DataBind();
            }
        }
        private const string layoutTemplateName = "Telerik.Sitefinity.Resources.Templates.PublicControls.CustomNavigationControl.ascx";
    }

    In one of the future updates it will be added the option of using the ASP.NET template parser for similar scenario like yours.

    Please mind that you can also use the standard NavigationControl with referenced Custom Template Path which points to a physical file and it uses the ASP.NET parser.

    All the best,
    George
    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
  7. Dallas Beek
    Dallas Beek avatar
    10 posts
    Registered:
    19 May 2010
    19 Jan 2011
    Link to this post

    Thank you for replying, your answer to the parsing is what I assumed.  I worked through it by creating a new sitemapdatasource as below.

    <%@ Control Language="C#" %>
    <asp:SiteMapDataSource ID="SiteMapDataSource1" runat="server" ShowStartingNode="false"
        ViewStateMode="Disabled" />
    <asp:Repeater runat="server" ID="menu" DataSourceID="SiteMapDataSource1">
        <HeaderTemplate>
            <div class="pageListWrap">
                <h1>
                    <asp:HyperLink ID="HyperLink1" runat="server" NavigateUrl='<%# Eval("Url") %>'><%# Eval("Title") %></asp:HyperLink>
                </h1>
        </HeaderTemplate>
        <ItemTemplate>
            <asp:SiteMapDataSource ID="SiteMapDataSource2" runat="server" ShowStartingNode="False"
                StartingNodeUrl='<%# Eval("Url") %>' ViewStateMode="Disabled" />
            <asp:Repeater runat="server" ID="menu" DataSourceID="SiteMapDataSource2">
                <ItemTemplate>
                    <li>
                        <asp:HyperLink ID="HyperLink2" runat="server" NavigateUrl='<%# Eval("Url") %>'><%# Eval("Title") %></asp:HyperLink>
                    </li>
                </ItemTemplate>
            </asp:Repeater>
        </ItemTemplate>
        <FooterTemplate>
            </div>
        </FooterTemplate>
    </asp:Repeater>
7 posts, 0 answered