Asked by:
composite control designer

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.
- protected override void Render(HtmlTextWriter writer)
- {
-
RenderContents(writer);
-
- }
- protected override void OnInit(System.EventArgs e)
- {
- base.OnInit(e)
- 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#
- public BorderStyle BorderStyle
- {
- get
- {
- String _BorderStyle = CStr(ViewState("BorderStyle"));
- If (_BorderStyle == Null) {
- return String.Empty
- } else {
- return _BorderStyle;
- }
- set (String Value)
- {
- ViewState("BorderStyle") = value;
- }
- }
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