There is a requirement: A customer would like to built a Custom CollapsiblePanel control. There are two contents of this control, the Header and the Content, both of them are Panels. His requirement is that we can place any control into the two contents by adding the HTML into the tag directly. The Custom Control also containers an AjaxControlToolkit CollapsiblePanelExtender to achieve the Collapse/Expand function for the Header and Content.
To achieve your goal, you can follow these steps:
1. We need to build a class which inherits the Panel Class and INamingContainer Interface. This class would be the Header and Content control’s base class.
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![ExpandedBlockStart.gif](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
2 using System.Collections.Generic;
3 using System.ComponentModel;
4 using System.Text;
5 using System.Web;
6 using System.Web.UI;
7 using System.Web.UI.WebControls;
8
9 namespace CustomCollapsiblePanel
10 {
11 public class CCPContainer : Panel, INamingContainer
12 {
13
14 }
15 }
2. In the CustomControl’s class, we create two properties Header and Content with the ITemplate type. Set the PersistenceModeAttribute with the value “InnerProperty”, then the two control would persist as a nested tag in the HTML.
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![ExpandedBlockStart.gif](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
2 /// Header Template
3 /// </summary>
4 [Browsable( false )]
5 [DefaultValue( null )]
6 [Description( " CollapisblePanel Header " )]
7 [PersistenceMode(PersistenceMode.InnerProperty)]
8 [TemplateContainer( typeof (CCPContainer))]
9 [TemplateInstance(TemplateInstance.Single)]
10 public virtual ITemplate Header
11 {
12 get { return _headerTemplate; }
13 set { _headerTemplate = value; }
14 }
15 /// <summary>
16 /// Content Template
17 /// </summary>
18 [Browsable( false )]
19 [DefaultValue( null )]
20 [Description( " CollapisblePanel Content " )]
21 [PersistenceMode(PersistenceMode.InnerProperty)]
22 [TemplateContainer( typeof (CCPContainer))]
23 [TemplateInstance(TemplateInstance.Single)]
24 public virtual ITemplate Content
25 {
26 get { return _contentTemplate; }
27 set { _contentTemplate = value; }
28 }
29
3. Create the Header Container and Content Container instance properties which are used to added into the CustomControl.
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![ExpandedBlockStart.gif](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
2 /// Header Container
3 /// </summary>
4 [Browsable( false )]
5 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
6 public CCPContainer HeaderContainer
7 {
8 get
9 {
10 EnsureChildControls();
11 return _header;
12 }
13 }
14
15 /// <summary>
16 /// Content Container
17 /// </summary>
18 [Browsable( false )]
19 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
20 public CCPContainer ContentContainer
21 {
22 get
23 {
24 EnsureChildControls();
25 return _content;
26 }
27 }
28
4. Add two CssClasses properties for the Header and Content.
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![ExpandedBlockStart.gif](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
2 /// Header CSS Class
3 /// </summary>
4 [Browsable( true )]
5 [Category( " Appearance " )]
6 [Description( " CSS class for CollapisblePanel Header " )]
7 public string HeaderCssClass
8 {
9 get
10 {
11 EnsureChildControls();
12 return _header.CssClass;
13 }
14 set
15 {
16 EnsureChildControls();
17 _header.CssClass = value;
18 }
19 }
20
21 /// <summary>
22 /// Content CSS Class
23 /// </summary>
24 [Browsable( true )]
25 [Category( " Appearance " )]
26 [Description( " CSS class for CollapisblePanel Content " )]
27 public string ContentCssClass
28 {
29 get
30 {
31 EnsureChildControls();
32 return _content.CssClass;
33 }
34 set
35 {
36 EnsureChildControls();
37 _content.CssClass = value;
38 }
39 }
40
5. In the override CreateChildControls function, add the Header, Content and an AjaxControlToolkit CollapsiblePanelExtender. Bind the corresponding controls with this extender. In the end, load the templates into the controls.
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![ExpandedBlockStart.gif](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
2 /// Instantiate the templates into new child controls
3 /// </summary>
4 protected override void CreateChildControls()
5 {
6 // Create the controls
7 Controls.Clear();
8 _header = new CCPContainer();
9 _header.ID = string .Format(System.Globalization.CultureInfo.InvariantCulture, " {0}_header " , this .ID);
10 Controls.Add(_header);
11 _content = new CCPContainer();
12 _content.ID = string .Format(System.Globalization.CultureInfo.InvariantCulture, " {0}_content " , this .ID);
13 Controls.Add(_content);
14
15 CollapsiblePanelExtender cpe = new CollapsiblePanelExtender();
16 cpe.ID = " cpe " ;
17 cpe.TargetControlID = _content.ID;
18 cpe.CollapseControlID = _header.ID;
19 cpe.ExpandControlID = _header.ID;
20 Controls.Add(cpe);
21
22 // Load the templates into the controls
23 if (_headerTemplate != null )
24 _headerTemplate.InstantiateIn(_header);
25 if (_contentTemplate != null )
26 _contentTemplate.InstantiateIn(_content);
27 }
28 }
6. Compile the custom control and add it into a page. Complete the property value.
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![ExpandedBlockStart.gif](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
2 HeaderCssClass = " collapsePanelHeader " >
3 < Header >
4 The Header
5 </ Header >
6 < Content >
7 The Content
8 < asp:Label ID = " Label1 " runat = " server " > FirstName: </ asp:Label >
9 < asp:TextBox ID = " TextBox1 " runat = " server " > LastName: </ asp:TextBox >
10 </ Content >
11 </ ccp:CusCollapsiblePanel >
7. The whole code:
The CusCollapsiblePanel.cs
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![ExpandedBlockStart.gif](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
2 using System.Collections.Generic;
3 using System.ComponentModel;
4 using System.Text;
5 using System.Web;
6 using System.Web.UI;
7 using System.Web.UI.WebControls;
8 using AjaxControlToolkit;
9
10 namespace CustomCollapsiblePanel
11 {
12 [ToolboxData( " <{0}:CusCollapsiblePanel runat=server></{0}:CusCollapsiblePanel> " )]
13 public class CusCollapsiblePanel : WebControl
14 {
15 #region private properties
16
17 /// <summary>
18 /// Header Container
19 /// </summary>
20 private CCPContainer _header;
21
22 /// <summary>
23 /// Header Template
24 /// </summary>
25 private ITemplate _headerTemplate;
26
27 /// <summary>
28 /// Content Container
29 /// </summary>
30 private CCPContainer _content;
31
32 /// <summary>
33 /// Content Template
34 /// </summary>
35 private ITemplate _contentTemplate;
36
37 #endregion
38
39 #region public properties
40
41 /// <summary>
42 /// Header Container
43 /// </summary>
44 [Browsable( false )]
45 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
46 public CCPContainer HeaderContainer
47 {
48 get
49 {
50 EnsureChildControls();
51 return _header;
52 }
53 }
54
55 /// <summary>
56 /// Header CSS Class
57 /// </summary>
58 [Browsable( true )]
59 [Category( " Appearance " )]
60 [Description( " CSS class for CollapisblePanel Header " )]
61 public string HeaderCssClass
62 {
63 get
64 {
65 EnsureChildControls();
66 return _header.CssClass;
67 }
68 set
69 {
70 EnsureChildControls();
71 _header.CssClass = value;
72 }
73 }
74
75 /// <summary>
76 /// Header Template
77 /// </summary>
78 [Browsable( false )]
79 [DefaultValue( null )]
80 [Description( " CollapisblePanel Header " )]
81 [PersistenceMode(PersistenceMode.InnerProperty)]
82 [TemplateContainer( typeof (CCPContainer))]
83 [TemplateInstance(TemplateInstance.Single)]
84 public virtual ITemplate Header
85 {
86 get { return _headerTemplate; }
87 set { _headerTemplate = value; }
88 }
89
90 /// <summary>
91 /// Content Container
92 /// </summary>
93 [Browsable( false )]
94 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
95 public CCPContainer ContentContainer
96 {
97 get
98 {
99 EnsureChildControls();
100 return _content;
101 }
102 }
103
104 /// <summary>
105 /// Content CSS Class
106 /// </summary>
107 [Browsable( true )]
108 [Category( " Appearance " )]
109 [Description( " CSS class for CollapisblePanel Content " )]
110 public string ContentCssClass
111 {
112 get
113 {
114 EnsureChildControls();
115 return _content.CssClass;
116 }
117 set
118 {
119 EnsureChildControls();
120 _content.CssClass = value;
121 }
122 }
123
124 /// <summary>
125 /// Content Template
126 /// </summary>
127 [Browsable( false )]
128 [DefaultValue( null )]
129 [Description( " CollapisblePanel Content " )]
130 [PersistenceMode(PersistenceMode.InnerProperty)]
131 [TemplateContainer( typeof (CCPContainer))]
132 [TemplateInstance(TemplateInstance.Single)]
133 public virtual ITemplate Content
134 {
135 get { return _contentTemplate; }
136 set { _contentTemplate = value; }
137 }
138
139 #endregion
140
141 /// <summary>
142 /// Instantiate the templates into new child controls
143 /// </summary>
144 protected override void CreateChildControls()
145 {
146 // Create the controls
147 Controls.Clear();
148 _header = new CCPContainer();
149 _header.ID = string .Format(System.Globalization.CultureInfo.InvariantCulture, " {0}_header " , this .ID);
150 Controls.Add(_header);
151 _content = new CCPContainer();
152 _content.ID = string .Format(System.Globalization.CultureInfo.InvariantCulture, " {0}_content " , this .ID);
153 Controls.Add(_content);
154
155 CollapsiblePanelExtender cpe = new CollapsiblePanelExtender();
156 cpe.ID = " cpe " ;
157 cpe.TargetControlID = _content.ID;
158 cpe.CollapseControlID = _header.ID;
159 cpe.ExpandControlID = _header.ID;
160 Controls.Add(cpe);
161
162 // Load the templates into the controls
163 if (_headerTemplate != null )
164 _headerTemplate.InstantiateIn(_header);
165 if (_contentTemplate != null )
166 _contentTemplate.InstantiateIn(_content);
167 }
168 }
169 }
The CCPContainer.cs
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![ExpandedBlockStart.gif](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
2 using System.Collections.Generic;
3 using System.ComponentModel;
4 using System.Text;
5 using System.Web;
6 using System.Web.UI;
7 using System.Web.UI.WebControls;
8
9 namespace CustomCollapsiblePanel
10 {
11 public class CCPContainer : Panel, INamingContainer
12 {
13
14 }
15 }
The TestCustomCollapsiblePanel.aspx
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![ExpandedBlockStart.gif](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
2 Inherits = " SoluTest_CustomControl.TestCustomCollapsiblePanel " %>
3
4 <% @ Register Assembly = " CustomCollapsiblePanel " Namespace = " CustomCollapsiblePanel "
5 TagPrefix = " ccp " %>
6 <! DOCTYPE html PUBLIC " -//W3C//DTD XHTML 1.0 Transitional//EN " " http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd " >
7 < html xmlns = " http://www.w3.org/1999/xhtml " >
8 < head runat = " server " >
9 < title ></ title >
10
11 < script runat = " server " >
12
13 Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
14 ' form1.Controls.Add(New CustomExtenders.CustomCollapsiblePanel())
15 End Sub
16
17 </ script >
18
19 < style type = " text/css " >
20 .collapseContainer
21 {
22 width: 500px;
23 overflow: visible;
24 }
25 .collapsePanel
26 {
27 border: medium solid #0000FF;
28 width: 450px;
29 background - color: white;
30 overflow: visible;
31 float : none;
32 }
33 .collapsePanelHeader
34 {
35 width: 450px;
36 height: 20px;
37 color: Yellow;
38 background - color: # 000080 ;
39 font - weight: bold;
40 float : none;
41 padding: 5px;
42 cursor: pointer;
43 vertical - align: middle;
44 }
45 </ style >
46 </ head >
47 < body >
48 < form id = " form1 " runat = " server " >
49 < div >
50 < asp:ScriptManager ID = " ScriptManager1 " runat = " server " >
51 </ asp:ScriptManager >
52 < ccp:CusCollapsiblePanel ID = " CusCollapsiblePanel1 " runat = " server " ContentCssClass = " collapsePanel "
53 HeaderCssClass = " collapsePanelHeader " >
54 < Header >
55 The Header
56 </ Header >
57 < Content >
58 The Content
59 < asp:Label ID = " Label1 " runat = " server " > FirstName: </ asp:Label >
60 < asp:TextBox ID = " TextBox1 " runat = " server " > LastName: </ asp:TextBox >
61 </ Content >
62 </ ccp:CusCollapsiblePanel >
63 </ div >
64 </ form >
65 </ body >
66 </ html >
8. The related Asp.Net thread URL:http://forums.asp.net/p/1499632/3553543.aspx#3553543
Best regards,
Zhi-Qiang Ni