Search code examples
c#asp.netcustom-server-controlsservercontrols

Creating nested ServerControl in asp.net?


I wanna create a server control like the following :

<%@ Register Assembly="MdsAccordionMenu" Namespace="MdsAccordionMenu" TagPrefix="cc1" %>

<cc1:MdsAccordionMenu ID="MdsAccordionMenu1" runat="server">
    <MdsAccordionMenuItem Title="Some Title">
        <MdsAccordionMenuItem Text="some text" Link="http://" IconUrl="image.png" />
        <MdsAccordionMenuItem Text="some text" Link="http://" IconUrl="image.png" />
        <MdsAccordionMenuItem Text="some text" Link="http://" IconUrl="image.png" />
        <MdsAccordionMenuItem Text="some text" Link="http://" IconUrl="image.png" />
    </MdsAccordionMenuItem>
</cc1:MdsAccordionMenu> 


I written the following c# code , but it doesn't work :

MdsAccordionMenu.cs :

namespace MdsAccordionMenu
{
    [ToolboxData("<{0}:MdsAccordionMenu runat=server></{0}:MdsAccordionMenu>")]
    [ParseChildren(true, "MdsAccordionMenuItems")]
    [DefaultProperty("MdsAccordionMenuItems")]
    [Serializable]
    public class MdsAccordionMenu : WebControl
    {
        [Description("سرعت نمایش انیمیشن")]
        [DefaultValue(500)]
        public int AnimationSpeed { get; set; }

        [Browsable(false), PersistenceMode(PersistenceMode.InnerProperty)]
        public List<MdsAccordionMenuItem> MdsAccordionMenuItems { get; set; }
    }
}


MdsAccordionMenuItem.cs :

namespace MdsAccordionMenu
{
    //[TypeConverter(typeof(ExpandableObjectConverter))]
    [ParseChildren(true, "MdsAccordionItems")]
    [DefaultProperty("Title")]
    [Serializable]
    public class MdsAccordionMenuItem
    {
        [Description("تیتر منو")]
        [DefaultValue("Title")]
        [NotifyParentProperty(true)]
        public string Title { get; set; }

        [Browsable(false), PersistenceMode(PersistenceMode.InnerProperty)]
        [NotifyParentProperty(true)]
        public List<MdsAccordionItem> MdsAccordionItems { get; set; }
    }
}


MdsAccordionItem .cs:

namespace MdsAccordionMenu
{
    [Serializable]
    public class MdsAccordionItem : INamingContainer
    {
        [NotifyParentProperty(true)]
        [Description("متن")]
        public string Text { get; set; }

        [NotifyParentProperty(true)]
        [Description("آدرس لینک منو")]
        public string Link { get; set; }

        [NotifyParentProperty(true)]
        [Description("آدرس آیکون")]
        public string ImageUrl { get; set; }
    }
}

How can I do it?


Solution

  • I could resolve the problem

    MdsAccordionMenu.cs

    [ToolboxData("<{0}:MdsAccordionMenu runat=server></{0}:MdsAccordionMenu>")]
    [ParseChildren(true, "MdsAccordionMenuItems")]
    [DefaultProperty("MdsAccordionMenuItems")]
    [PersistChildren(true)]
    [TypeConverter(typeof(ExpandableObjectConverter))]
    [Serializable]
    public sealed class MdsAccordionMenu : WebControl, INamingContainer
    {
        #region Properties
    
        public int AnimationSpeed { get; set; }
    
        public string InlineStyle { get; set; }
    
        [Bindable(true)]
        [Browsable(false), PersistenceMode(PersistenceMode.InnerProperty)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        public MdsAccordionMenuItemsClass MdsAccordionMenuItems
        {
            get { return _mdsAccordionMenuItem ?? new MdsAccordionMenuItemsClass(); }
            set { _mdsAccordionMenuItem = value; }
        }
    
        private MdsAccordionMenuItemsClass _mdsAccordionMenuItem;
    }
    

    MdsAccordionMenuItem.cs

    [Serializable]
    public class MdsAccordionMenuItemsClass : List<MdsAccordionMenuItem>
    {
    
    }
    
    [ParseChildren(true, "MdsAccordionItems")]
    [PersistChildren(true)]
    [Serializable]
    public class MdsAccordionMenuItem : INamingContainer
    {
        public string Title { get; set; }
    
        private MdsAccordionItemsClass _mdsAccordionItems;
    
        [Browsable(false), PersistenceMode(PersistenceMode.InnerProperty)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        [Bindable(true)]
        public MdsAccordionItemsClass MdsAccordionItems
        {
            get { return _mdsAccordionItems ?? new MdsAccordionItemsClass(); }
            set { _mdsAccordionItems = value; }
        }
    }
    

    MdsAccordionItem.cs

    [Serializable]
    public class MdsAccordionItemsClass : List<MdsAccordionItem>
    {
    
    }
    
    [Serializable]
    [ParseChildren(true, "MdsAccordionSubMenuItems")]
    [PersistChildren(true)]
    public class MdsAccordionItem : INamingContainer
    {
        public string Text { get; set; }
    
        private bool _visible = true;
        public bool Visible
        {
            get { return this._visible; } 
            set { this._visible = value; }
        }
    
        public string Link { get; set; }
    
        public string ImageUrl { get; set; }
    
        private MdsAccordionItemsClass _mdsAccordionSubMenuItems;
    
        [Bindable(true)]
        [Browsable(false), PersistenceMode(PersistenceMode.InnerProperty)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        public MdsAccordionItemsClass MdsAccordionSubMenuItems
        {
            get { return _mdsAccordionSubMenuItems ?? new MdsAccordionItemsClass(); }
            set { _mdsAccordionSubMenuItems = value; }
        }
    }
    

    Now, I can create the control in designer mode with the following code :

    <cc1:MdsAccordionMenu ID="MdsAccordionMenu1" runat="server" EnableViewState="True">
        <MdsAccordionMenuItems>
            <cc1:MdsAccordionMenuItem Title="Submit">
                <MdsAccordionItems>
                    <cc1:MdsAccordionItem Text="Item 01" Link="#" ImageUrl="~/style/icons/lightbulb.png" />
                    <cc1:MdsAccordionItem Text="Item 02" Link="#" ImageUrl="~/style/myImages/question.png" />
                    <cc1:MdsAccordionItem Text="Item 03" Link="#" ImageUrl="~/style/myImages/request-knowledge.png" />
                    <cc1:MdsAccordionItem Text="Item 04" Link="#" ImageUrl="~/style/myImages/document.png" />
                    <cc1:MdsAccordionItem Text="Item 05" Link="#" ImageUrl="~/style/myImages/book.png" />
                    <cc1:MdsAccordionItem Text="Item 06" Link="#" ImageUrl="~/style/myImages/document1.png" />
                </MdsAccordionItems>
            </cc1:MdsAccordionMenuItem>
        </MdsAccordionMenuItems>
    </cc1:MdsAccordionMenu>