Introduction
Ajax Control Toolkit allows the developer to create Web applications that can update data on the Web page without a complete reload of the page, and contain many controls with very interesting features: popup panels, resizable controls, floating controls and others.
Often you want a control with some features of some other controls, so you can achieve the goal of joining more controls in a single control as CompositeControl
.
Composite Controls are controls that combine multiple controls together to form a new reusable control. For example, I want to create a control container that makes resizable, collapsible, draggable all guest controls as IFrame
or others.
ResizableControlExtender
, CollapsiblePanelextender
, DragPanelExtender
controls extend their own features to the Panel
written on TargetControlID
property so you can create a mix like this:
Background
This is a graphic representation of the control...
... and this is the code, built in the page, of the control described in the bitmap above.
<%----%>
...
<%----%>
<asp:Panel ID="PanelContainer" runat="server" Visible="false"
style="Left:200px; Position:absolute; Top:100px;">
<%----%>
<asp:Panel ID="PanelClose" runat="server" Height="20px">
<asp:ImageButton ID="ImageButton1"
runat="server" style="cursor: hand"
ImageAlign="Right" Height="100%" ImageUrl="~/images/close.gif"
onclick="ImageButton1_Click" />
</asp:Panel>
<%----%>
<asp:Panel ID="PanelHeader" runat="server" style="cursor: hand" Height="20px"
BackImageUrl="~/images/RoundedGrayExplorer.gif">
</asp:Panel>
<%----%>
<asp:Panel ID="PanelBody" runat="server" BorderStyle="Solid" BorderWidth="1px">
<iframe id="ieframe" scrolling="auto" runat="server"
src="HTMLPage.htm"
height="100%"
width="100%">
</iframe >
</asp:Panel>
</asp:Panel>
<%----%>
...
<%----%>
...
Now we will convert it in a redistributable Composite Control.
Using the Code
In order to test the control build in the page, set AjaxCompositePanelBuildInPage.aspx as the project start page.
In order to test the composite control, set AjaxCompositePanelBuildInControl.aspx as the project start page.
Points of Interest
A composite control class AjaxCompositePanel
inside AjaxCompositePanel.cs file inherits from the CompositeControl
class, and has some class attributes...
[ToolboxBitmap(typeof(View))]
[ToolboxData("<{0}:AjaxCompositePanel runat="server">")]
[Designer("AjaxCompositePanelControl.AjaxCompositePanelDesigner")]
public class AjaxCompositePanel : CompositeControl
{
...
... and some method attributes for design-time behaviors inside Visual Studio properties window:
[Browsable(true)]
[Category("AjaxCompositePanel")]
[DefaultValue("")]
[Description("Url of header image.")]
[Localizable(true)]
[RefreshProperties(RefreshProperties.Repaint)]
[UrlProperty]
[EditorAttribute(typeof(System.Web.UI.Design.ImageUrlEditor),
typeof(System.Drawing.Design.UITypeEditor))]
public string BarImageUrl
{
...
The main method of Custom Control is method named CreateChildControls
which can be overridden, that calls CreateControlsHierarchy()
within which a tree structure of the child control is built and added to the controls collection:
protected virtual void CreateControlsHierarchy()
{
...
Panel DragebleResizablePanelContainer = new Panel();
DragebleResizablePanelContainer.ID = "DragebleResizablePanelContainer";
DragebleResizablePanelContainer.Visible = false;
DragebleResizablePanelContainer.Attributes["style"] = "float: right";
Panel DrageblePanelHeader = new Panel();
DrageblePanelHeader.ID = "DrageblePanelHeader";
DrageblePanelHeader.Attributes["style"] = "cursor: hand";
DragebleResizablePanelContainer.Controls.Add(DrageblePanelHeader);
Controls.Add(DragebleResizablePanelContainer);
...
Composite Control client side behavior will need JavaScript methods that will be added to the page...
if (!Page.ClientScript.IsClientScriptBlockRegistered("clientScript"))
{
System.Text.StringBuilder sb = new System.Text.StringBuilder();
sb.Append("<script type="\"text/javascript\""></script>");
Page.ClientScript.RegisterClientScriptBlock(this.GetType(),
"clientScript", sb.ToString(),false);
}
//Adds a script block into the page that executes when the page
//finishes loading but before the page's onload event is raised.
if (!Page.ClientScript.IsStartupScriptRegistered("repositioningScript"))
{
//Page.ClientScript.RegisterStartupScript(this.GetType(),
//"clientScript", sb.ToString(), false);
}
... and also a stylesheet class used for Ajax Panel Extender will be added to the page:
protected virtual void CreateControlsHierarchy()
{ ...
this.Page.Header.StyleSheet.CreateStyleRule(new ResizingIFrameCssClass(),
this.Page, ".resizingIFrame");
...
}
...
class ResizingIFrameCssClass : Style
{
protected override void FillStyleAttributes
(CssStyleCollection attributes, IUrlResolutionService urlResolver)
{
base.FillStyleAttributes(attributes, urlResolver);
attributes[HtmlTextWriterStyle.Padding] = "0px";
attributes[HtmlTextWriterStyle.BorderStyle] = "solid";
attributes[HtmlTextWriterStyle.BorderWidth] = "2px";
attributes[HtmlTextWriterStyle.BorderColor] = "#B4D35D";
}
}
At the end, only one word on Design-Time rendering of the control.
Inside AjaxCompositePanelDesigner.cs, you can see the AjaxCompositePanelDesigner
class that inherits from the CompositeControlDesigner
class, and GetDesignTimeHtml
method which can be overridden that retrieves the HTML markup used to render the control at design time.
History
- 28th November, 2008: Initial version