locked
composite control designer RRS feed

  • Question

  • User1835401063 posted

    Hello

    I'm trying to develope a collapsible panel control with designer.

    I have the following two classes:

    using System;
    using System.ComponentModel;
    using System.ComponentModel.Design;
    using System.Drawing;
    using System.Web.UI;
    using System.Web.UI.Design;
    using System.Web.UI.Design.WebControls;
    using System.Web.UI.WebControls;
    
    /// <summary>
    /// Summary description for NumericTB
    /// </summary>
    /// 
    namespace T1
    {
        [ToolboxBitmap("~/Pictures/Collapse.gif")]
        [Designer(typeof(CustomCollapsiblePanelDesigner)),ToolboxData("<{0}:CustomCollapsiblePanel runat=\"server\" ></{0}:CustomCollapsiblePanel>")]
        [Themeable(false)]
        public class CustomCollapsiblePanel: CompositeControl
        {
            string expandtext = "";
            string collapsetext = "";
    
            protected Panel Header = new Panel();
            Label L = new Label();
            System.Web.UI.WebControls.Image img = new System.Web.UI.WebControls.Image();
            AjaxControlToolkit.RoundedCornersExtender RC1 = new AjaxControlToolkit.RoundedCornersExtender();
            AjaxControlToolkit.CollapsiblePanelExtender CPE = new AjaxControlToolkit.CollapsiblePanelExtender();
            protected Panel Body = new Panel();
    
            [PersistenceMode(PersistenceMode.InnerProperty), DefaultValue(null)]
            public virtual Panel BodyView
            {
                get { return Body; }
                set { Body = value; }
            }
    
    
            public CustomCollapsiblePanel()
            {
            }
    
            protected override void CreateChildControls()
            {
                Controls.Clear();
    
                L.ID = "L";
                img.ID = "IMG";
    
                Header.ID = "H1";
                Header.Controls.Add(img);
                Header.Controls.Add(L);
                Header.BorderStyle = System.Web.UI.WebControls.BorderStyle.None;
                RC1.TargetControlID = "H1";
                RC1.Corners = AjaxControlToolkit.BoxCorners.Top;
                RC1.Radius = 4;
    
                Body.ID = "Body";
                Body.BorderColor = BorderColor;
                Body.BorderStyle = BorderStyle;
                Body.BorderWidth = BorderWidth;
                Body.Width = Width;
    
                CPE.ID = "CPE";
                CPE.TargetControlID = "Body";
                CPE.CollapseControlID = "H1";
                CPE.ExpandControlID = "H1";
                CPE.TextLabelID = "L";
                CPE.ImageControlID = "IMG";
                CPE.ExpandedText = ExpandText;
                CPE.CollapsedText = CollapseText;
                CPE.CollapsedSize = 0;
                CPE.Collapsed = true;
                CPE.ExpandedImage = "~/Pictures/Expand.gif";
                CPE.CollapsedImage = "~/Pictures/Collapse.gif";
                
                this.Controls.Add(Header);
                this.Controls.Add(RC1);
                this.Controls.Add(Body);
                this.Controls.Add(CPE);
                base.CreateChildControls();
            }
            protected override void Render(HtmlTextWriter writer)
            {
                this.EnsureChildControls();
                base.Render(writer);
            }
    
            public string ExpandText
            {
                get { return expandtext; }
                set { expandtext = value; }
            }
            public string CollapseText
            {
                get { return collapsetext; }
                set { collapsetext = value; }
            }
    
            public Unit Width
            {
                get { return (Header.Width); }
                set
                {
                    Header.Width = value;
                }
            }
            public Unit Height
            {
                get { return (Header.Height); }
                set
                {
                    Header.Height = value;
                }
            }
    
            [Bindable(true), Category("Appearance"), DefaultValue("#00bb00")]
            public Color BackColor
            {
                get
                {
                    return base.BackColor;
                }
                set
                {
                    Header.BackColor = value;
                }
            }
    
            public BorderStyle BorderStyle
            {
                get
                {
                    return Header.BorderStyle;
                }
                set
                {
                    Header.BorderStyle = value;
                }
            }
            public Color BorderColor
            {
                get
                {
                    return Header.BorderColor;
                }
                set
                {
                    Header.BorderColor = value;
                }
            }
            public Unit BorderWidth
            {
                get
                {
                    return Header.BorderWidth;
                }
                set
                {
                    Header.BorderWidth = value;
                }
            }
    
            public Color ForeColor
            {
                get
                {
                    return base.ForeColor;
                }
                set
                {
                    L.ForeColor = value;
                }
            }
            public string SkinID
            {
                get
                {
                    return base.SkinID;
                }
                set
                {
                    Header.SkinID = value;
                }
            }
        }
    }


     

     

    and this one:

    using System;
    using System.ComponentModel;
    using System.ComponentModel.Design;
    using System.Drawing;
    using System.Web.UI;
    using System.Web.UI.Design;
    using System.Web.UI.Design.WebControls;
    using System.Web.UI.WebControls;
    using System.IO;
    
    /// <summary>
    /// Summary description for CustomCollapsiblePanelDesigner
    /// </summary>
    /// 
    namespace T1
    {
    
        public class CustomCollapsiblePanelDesigner : CompositeControlDesigner
        {
            CustomCollapsiblePanel FControllo;
    
            public override void Initialize(System.ComponentModel.IComponent component)
            {
                base.Initialize(component);
                this.FControllo = (CustomCollapsiblePanel)component;
            }
    
            public override bool AllowResize
            {
                get
                {
                    return true;
                }
            }
    
            protected override void CreateChildControls()
            {
                base.CreateChildControls();
                Panel P=null;
                foreach (Control C in FControllo.Controls)
                {
                    if (C.ID == "Body")
                    {
                        P = (Panel)C;
                        P.Attributes[DesignerRegion.DesignerRegionAttributeName] = "0";
                    }
                }
            }
    
            public override string  GetDesignTimeHtml(DesignerRegionCollection regions)
            {
                EditableDesignerRegion editableRegion =
                    new EditableDesignerRegion(this,
                        "Content" + FControllo.BodyView.ID, false);
                regions.Add(editableRegion);
    
                // Use the base class to render the markup
                return base.GetDesignTimeHtml();
            }
    
            // Get the content string for the selected region. Called by the designer host?
            public override string GetEditableDesignerRegionContent(EditableDesignerRegion region)
            {
                // Get a reference to the designer host
                IDesignerHost host = (IDesignerHost)Component.Site.GetService(typeof(IDesignerHost));
                return ControlPersister.PersistControl(FControllo.BodyView, host);
            }
    
    
            protected override string GetEmptyDesignTimeHtml()
            {
                return "<table><tr><td>" + typeof(CustomCollapsiblePanel) + " " + FControllo.ID + "</td></tr></table>";
            }
    
            /*protected override string GetErrorDesignTimeHtml(Exception e)
            {
                return CreatePlaceHolderDesignTimeHtml(e.Message);
            }*/
        }
    }


     

     

    In fact, the designer class is a copy of a sample class in MSDN and I only tried to customize it to work for me. I'm not sure if all methods are necessary or not.

     

    I have the following two questions:

    1- When I use this contrl in design mode, I can add or delete controls to it, in the html view, tags are not updated. so when I close the page and open it again, all changes are lost.

     

    2- I have added this control to the same asp.net project that is using this control. Isn't there any way to have this controil in tool box?

     

    3- Any other comments on this code part will be appreciated.

    Thanks in advance

     

    Friday, January 22, 2010 11:45 AM

All replies

  • User-16411453 posted

    Not the anwser, but just change it. You have to set the property in order to write the attribute to the tag, and have it stick.

    1. protected override void Render(HtmlTextWriter writer)  
    2.         {  
    3.             RenderContents(writer); 
    4.              
    5.         } 
    1.  protected override void OnInit(System.EventArgs e)  
    2.         { 
    3.             base.OnInit(e)
    4.             Controls.Clear(); 

    I don't code in c#, so excuse the mistakes. It may not be 100% right, I'm attempting to translate my vb to c#

    1.  public BorderStyle BorderStyle  
    2.         {  
    3.             get  
    4.             {
    5.                String _BorderStyle = CStr(ViewState("BorderStyle"));
    6.                If (_BorderStyle == Null) {
    7.                 return String.Empty
    8.                } else { 
    9.                 return _BorderStyle;  
    10.             }  
    11.             set (String Value)
    12.             {  
    13.                 ViewState("BorderStyle") = value;  
    14.             }  
    15.         } 
    Friday, January 22, 2010 8:00 PM
  • User1835401063 posted

    Hello

     

    Thanks for youur answer, but this was not  my problem. In fact when I change a property in designer, code behind is updated automatically.

     

    My problem was when I add controls to panel called "Body", then code behind is not updated.

     

    Thanks

    Saturday, January 23, 2010 1:18 PM
  • User1835401063 posted

    Hello

     

    No answer?

     

    thanks 

    Monday, January 25, 2010 11:49 AM
  • User-16411453 posted

    I looked at your code again, and no code was added to body. Maybe that's why nothing show up

    body.controls.add(someother_Control)

    By the way, the first line in my post said this is not the anwser.

    I admire your courage to build a server control, and your on the right track. But first you need to take a step back and learn how to create a webpage or just part of the page in pure code first. When your able to fully understand the logic behind creating pure code stuff, then go back to build the server control. Your server control framework looks fine, but your dynamic object code needs linking or interaction. Look at the example below to see how the parts link together

    UpdatePanel_RecentPayment_Index = New UpdatePanel
            With UpdatePanel_RecentPayment_Index
                .ID = [ID] & "_UpdatePanel_RecentPayment_Index"
                .ChildrenAsTriggers = True
                .UpdateMode = UpdatePanelUpdateMode.Conditional
            End With
            Controls.Add(UpdatePanel_RecentPayment_Index)

            Dim panel_RecentPayment_Index As Panel
            panel_RecentPayment_Index = New Panel
            With panel_RecentPayment_Index
                .ID = [ID] & "_panel_RecentPayment_Index"
                .Visible = [Visible]
                .Style.Add(HtmlTextWriterStyle.Width, [Width].ToString)
                .Style.Add(HtmlTextWriterStyle.TextAlign, "center")
                .Style.Add(HtmlTextWriterStyle.Margin, "0px auto")
            End With
            UpdatePanel_RecentPayment_Index.ContentTemplateContainer.Controls.Add(panel_RecentPayment_Index)

            Dim table_RecentPayment_Index As Table
            table_RecentPayment_Index = New Table
            With table_RecentPayment_Index
                .CellPadding = 0
                .CellSpacing = 0
                .Width = [Width]
                .CssClass = [CssClass]
                .ToolTip = [ToolTip]
                '.Attributes.Add("Border", "1")
            End With
            panel_RecentPayment_Index.Controls.Add(table_RecentPayment_Index)

    Wednesday, January 27, 2010 6:35 PM
  • User1835401063 posted

     Hello

     

    I have modified the code like this; this is mostly combining my code with another code sample on the net. I have added ITemplate to my control

     

    using System;
    using System.ComponentModel;
    using System.ComponentModel.Design;
    using System.Drawing;
    using System.Web.UI;
    using System.Web.UI.Design;
    using System.Web.UI.Design.WebControls;
    using System.Web.UI.WebControls;
    
    /// <summary>
    /// Summary description for NumericTB
    /// </summary>
    /// 
    namespace T1
    {
        [ToolboxBitmap("~/Pictures/Collapse.gif")]
        //[Designer(typeof(CustomCollapsiblePanelDesigner)),ToolboxData("<{0}:CustomCollapsiblePanel runat=\"server\" ></{0}:CustomCollapsiblePanel>")]
        //[PersistChildren(true)]
        //[Themeable(false)]
        public class CustomCollapsiblePanel: CompositeControl
        {
            #region internals
                string expandtext = "";
                string collapsetext = "";
                
                protected Panel Header = new Panel();
                Label L = new Label();
                System.Web.UI.WebControls.Image img = new System.Web.UI.WebControls.Image();
                AjaxControlToolkit.RoundedCornersExtender RC1 = new AjaxControlToolkit.RoundedCornersExtender();
                AjaxControlToolkit.CollapsiblePanelExtender CPE = new AjaxControlToolkit.CollapsiblePanelExtender();
                protected Panel Body=new Panel();
                public ITemplate _BodyTemplate;
                
                //[PersistenceMode(PersistenceMode.InnerProperty), DefaultValue(null)]
                public virtual Panel BodyView
                {
                    get { return Body; }
                    set { Body = value; }
                }
                public virtual ITemplate BodyTemplate
                {
                    get { return _BodyTemplate; }
                    set { _BodyTemplate = value; }
                }
            #endregion
    
            #region Methods
                protected override void CreateChildControls()
                {
                    Controls.Clear();
    
                    L.ID = "L";
                    img.ID = "IMG";
    
                    Header.ID = "H1";
                    Header.Controls.Add(img);
                    Header.Controls.Add(L);
                    Header.BorderStyle = System.Web.UI.WebControls.BorderStyle.None;
                    RC1.TargetControlID = "H1";
                    RC1.Corners = AjaxControlToolkit.BoxCorners.Top;
                    RC1.Radius = 4;
    
                    Body.ID = "Body";
                    Body.BorderColor = BorderColor;
                    Body.BorderStyle = BorderStyle;
                    Body.BorderWidth = BorderWidth;
                    Body.Width = Width;
    
                    CPE.ID = "CPE";
                    CPE.TargetControlID = "Body";
                    CPE.CollapseControlID = "H1";
                    CPE.ExpandControlID = "H1";
                    CPE.TextLabelID = "L";
                    CPE.ImageControlID = "IMG";
                    CPE.ExpandedText = ExpandText;
                    CPE.CollapsedText = CollapseText;
                    CPE.CollapsedSize = 0;
                    CPE.Collapsed = true;
                    CPE.ExpandedImage = "~/Pictures/Expand.gif";
                    CPE.CollapsedImage = "~/Pictures/Collapse.gif";
    
                    this.Controls.Add(Header);
                    this.Controls.Add(RC1);
                    this.Controls.Add(Body);
                    this.Controls.Add(CPE);
    
                    base.CreateChildControls();
    
                    BodyTemplate.InstantiateIn(Body);
                }
                /*protected override void Render(HtmlTextWriter writer)
                {
                    this.EnsureChildControls();
                    base.Render(writer);
                }*/
                protected override void OnPreRender(EventArgs e)
                {
                    base.OnPreRender(e);
                    if (DesignMode)
                    {
                        BodyTemplate.InstantiateIn(Body);
                    }
                }
            #endregion
    
            #region public properties
                public string ExpandText
                {
                    get { return expandtext; }
                    set { expandtext = value; }
                }
                public string CollapseText
                {
                    get { return collapsetext; }
                    set { collapsetext = value; }
                }
                public Unit Width
                {
                    get { return (Header.Width); }
                    set
                    {
                        Header.Width = value;
                    }
                }
                public Unit Height
                {
                    get { return (Header.Height); }
                    set
                    {
                        Header.Height = value;
                    }
                }
                [Bindable(true), Category("Appearance"), DefaultValue("#00bb00")]
                public Color BackColor
                {
                    get
                    {
                        return base.BackColor;
                    }
                    set
                    {
                        Header.BackColor = value;
                    }
                }
                public BorderStyle BorderStyle
                {
                    get
                    {
                        return Header.BorderStyle;
                    }
                    set
                    {
                        Header.BorderStyle = value;
                    }
                }
                public Color BorderColor
                {
                    get
                    {
                        return Header.BorderColor;
                    }
                    set
                    {
                        Header.BorderColor = value;
                    }
                }
                public Unit BorderWidth
                {
                    get
                    {
                        return Header.BorderWidth;
                    }
                    set
                    {
                        Header.BorderWidth = value;
                    }
                }
                public Color ForeColor
                {
                    get
                    {
                        return base.ForeColor;
                    }
                    set
                    {
                        L.ForeColor = value;
                    }
                }
                public string SkinID
                {
                    get
                    {
                        return base.SkinID;
                    }
                    set
                    {
                        Header.SkinID = value;
                    }
                }
            #endregion
        }
    }


     

    using System;
    using System.ComponentModel;
    using System.ComponentModel.Design;
    using System.Drawing;
    using System.Web.UI;
    using System.Web.UI.Design;
    using System.Web.UI.Design.WebControls;
    using System.Web.UI.WebControls;
    using System.IO;
    
    /// <summary>
    /// Summary description for CustomCollapsiblePanelDesigner
    /// </summary>
    /// 
    namespace T1
    {
        [SupportsPreviewControl(true)]
        public class CustomCollapsiblePanelDesigner : CompositeControlDesigner
        {
            CustomCollapsiblePanel FControllo;
            public override bool AllowResize
            {
                get
                {
                    return true;
                }
            }
    
            public override void Initialize(System.ComponentModel.IComponent component)
            {
                base.Initialize(component);
                FControllo = (CustomCollapsiblePanel)component;
            }
    
    
            public override string GetDesignTimeHtml(DesignerRegionCollection regions)
            {
                EditableDesignerRegion editableRegion = new EditableDesignerRegion(this, "Content", false);
                regions.Add(editableRegion);
    
                // Use the base class to render the markup
                return base.GetDesignTimeHtml();
            }
    
            protected override void CreateChildControls()
            {
                base.CreateChildControls();
                FControllo.Attributes[DesignerRegion.DesignerRegionAttributeName] = "0";
                /*
                Panel P=null;
                foreach (Control C in FControllo.Controls)
                {
                    if (C.ID == "Body")
                    {
                        P = (Panel)C;
                        P.Attributes[DesignerRegion.DesignerRegionAttributeName] = "0";
                    }
                }*/
            }
    
    
            // Get the content string for the selected region. Called by the designer host?
            public override string GetEditableDesignerRegionContent(EditableDesignerRegion region)
            {
                // Get a reference to the designer host
                IDesignerHost host = (IDesignerHost)Component.Site.GetService(typeof(IDesignerHost));
                return ControlPersister.PersistTemplate(FControllo.BodyTemplate,host);
            }
    
            public override void SetEditableDesignerRegionContent(EditableDesignerRegion region, string content)
            {
                if (content == null)
                    return;
    
                // Get a reference to the designer host
                IDesignerHost host = (IDesignerHost)Component.Site.GetService(typeof(IDesignerHost));
                if (host != null)
                {
                    // Create a template from the content string
                    ITemplate template = ControlParser.ParseTemplate(host, content);
                }
            }
        }
    }


     

     

     

    Now when I use the code I see this error:

    An unhandled error has occured.

    Object reference not set to an instance of an object.

     

    Could you please help? And how can I debug this code part during design time?

    Thanks

     

     

    Sunday, January 31, 2010 2:07 PM