Custom Menu using Repeater

Posted by Community Admin on 03-Aug-2018 21:13

Custom Menu using Repeater

All Replies

Posted by Community Admin on 13-Jan-2011 00:00

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" />

Posted by Community Admin on 13-Jan-2011 00:00

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

Posted by Community Admin on 13-Jan-2011 00:00

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

 

Posted by Community Admin on 13-Jan-2011 00:00

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

Posted by Community Admin on 13-Jan-2011 00:00

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. 

Posted by Community Admin on 19-Jan-2011 00:00

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

Posted by Community Admin on 19-Jan-2011 00:00

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>

This thread is closed