Gideon de Swardt wrot here is my code for the Control and ASP.NET Page
Controls Code
using System;
using System.Web.UI;
namespace abo.Web
{
/// <summary>Represents an .aspx file, also known as a Web Forms page,
requested from a server that hosts an ASP.NET Web application.</summary>
[ParseChildren(true), PersistChildren(false)]
public class Template : Control, INamingContainer
{
#region Controls
System.Web.UI.WebControls.PlaceHolder ctlBody = new
System.Web.UI.WebControls.PlaceHolder();
System.Web.UI.WebControls.PlaceHolder ctlHead = new
System.Web.UI.WebControls.PlaceHolder();
System.Web.UI.HtmlControls.HtmlGenericControl lblTitle = new
System.Web.UI.HtmlControls.HtmlGenericControl();
abo.Web.SiteStyle ctlSiteStyle = new abo.Web.SiteStyle();
abo.Web.Javascript ctlJavaScript = new abo.Web.Javascript();
abo.Web.MenuBar ctlMenuBar = new abo.Web.MenuBar();
abo.Web.NavBar ctlNavBar = new abo.Web.NavBar();
abo.Web.TabBar ctlTabBar = new abo.Web.TabBar();
abo.Web.Footer ctlFooter = new abo.Web.Footer();
#endregion
#region Properties
/// <summary>Gets or set the Object the current page is attached
to.</summary>
/// <value>A string containing the name of the Object the current page is
attached to.</value>
public string Object
{
get
{
if (this._Object == null)
{
this._Object = this.ctlTabBar.Object;
}
return(this._Object);
}
set
{
this._Object = value;
this.ctlMenuBar.Object = value;
this.ctlNavBar.Object = value;
this.ctlTabBar.Object = value;
}
}
/// <summary>Gets or sets the Title of the page.</summary>
/// <value>A string containing the title of the page</value>
/// <remarks>If the Title is not set to anything it would use the
Config.SystemName</remarks>
public string Title
{
get
{
if (this.lblTitle.InnerHtml.Length == 0)
{
this.lblTitle.InnerHtml = Config.SystemName;
}
return(this.lblTitle.InnerHtml);
}
set {this.lblTitle.InnerHtml = value;}
}
/// <summary>Gets or sets a value that indicates whether the MenuBar
control is rendered as UI on the page.</summary>
/// <value>true if the control is visible on the page; otherwise
false</value>
public bool ScriptVisible
{
get {return(this.ctlJavaScript.Visible);}
set {this.ctlJavaScript.Visible = value;}
}
/// <summary>Gets or sets a value that indicates whether the MenuBar
control is rendered as UI on the page.</summary>
/// <value>true if the control is visible on the page; otherwise
false</value>
public bool MenuVisible
{
get {return(this.ctlMenuBar.Visible);}
set {this.ctlMenuBar.Visible = value;}
}
/// <summary>Gets or sets a value that indicates whether the NavBar
control is rendered as UI on the page.</summary>
/// <value>true if the control is visible on the page; otherwise
false</value>
public bool NavVisible
{
get {return(this.ctlNavBar.Visible);}
set {this.ctlNavBar.Visible = value;}
}
/// <summary>Gets or sets a value that indicates whether the NavBar
control is rendered as UI on the page.</summary>
/// <value>true if the control is visible on the page; otherwise
false</value>
public bool TabVisible
{
get {return(this.ctlTabBar.Visible);}
set {this.ctlTabBar.Visible = value;}
}
/// <summary>Gets or sets a value that indicates whether the NavBar
control is rendered as UI on the page.</summary>
/// <value>true if the control is visible on the page; otherwise
false</value>
public bool FooterVisible
{
get {return(this.ctlFooter.Visible);}
set {this.ctlFooter.Visible = value;}
}
/// <summary>Defines the Body to implement for for the template.</summary>
/// <value>ITemplate containing the child controls that needs to included
in the Body</value>
public ITemplate Body
{
get {return(this._Body);}
set {this._Body = value;}
}
/// <summary>Defines the Head to implement for for the template.</summary>
/// <value>ITemplate containing the child controls that needs to included
in the Head</value>
public ITemplate Head
{
get {return(this._Head);}
set {this._Head = value;}
}
#endregion
#region Member Variables
/// <summary>Holds the value of the Object property.</summary>
private string _Object;
/// <summary>Holds the value of the Title property.</summary>
private ITemplate _Body;
/// <summary>Holds the value of the Title property.</summary>
private ITemplate _Head;
#endregion
protected override void CreateChildControls()
{
this.lblTitle.TagName = "title";
if (this.Body != null)
{
this.Body.InstantiateIn(this.ctlBody);
}
if (this.Head != null)
{
this.Head.InstantiateIn(this.ctlHead);
}
Controls.Add(new LiteralControl("<html>\r\n"));
Controls.Add(new LiteralControl("\t<head>\r\n"));
Controls.Add(new LiteralControl("\t\t"));
Controls.Add(this.lblTitle);
Controls.Add(new LiteralControl("\r\n\t\t"));
Controls.Add(this.ctlSiteStyle);
Controls.Add(new LiteralControl("\r\n\t\t"));
Controls.Add(this.ctlJavaScript);
Controls.Add(new LiteralControl("\r\n\t\t"));
Controls.Add(this.ctlHead);
Controls.Add(new LiteralControl("\r\n\t</head>\r\n"));
Controls.Add(new LiteralControl("\t<body>\r\n"));
Controls.Add(this.ctlMenuBar);
Controls.Add(this.ctlNavBar);
Controls.Add(this.ctlTabBar);
Controls.Add(this.ctlBody);
Controls.Add(this.ctlFooter);
Controls.Add(new LiteralControl("\t</body>\r\n"));
Controls.Add(new LiteralControl("</html>"));
}
protected override void Render(HtmlTextWriter writer)
{
if (this.lblTitle.InnerHtml.Length == 0)
{
this.lblTitle.InnerHtml = Config.SystemName;
}
base.Render (writer);
}
}
}
The ASPX Page
<%@ Register TagPrefix="abo" Namespace="abo.Web" Assembly="abo.Web" %>
<%@ Page language="c#" Codebehind="ObjectSearch.aspx.cs"
AutoEventWireup="false" Inherits="abo.Web.Library.Object.ObjectSearch" %>
<abo:template id="PageTemplate" runat="server">
<body>
<form id="formObjectSearch" method="post" runat="server">
<center>
<abo:ObjectSearch id="xmlObjectSearch" runat="server"
TransformSource="ObjectSearch.xslt" width="100%"
Label="Object Search"></abo:ObjectSearch></center>
</form>
</body>
</abo:template>
The Code Behind
using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using abo.BusinessLayer;
namespace abo.Web.Library.Object
{
/// <summary>
/// Summary description for ObjectSearch.
/// </summary>
public class ObjectSearch : abo.Web.Page
{
protected abo.Web.ObjectSearch xmlObjectSearch;
private void Page_Load(object sender, System.EventArgs e)
{
this.SetData();
}
private void SetData()
{
if (!this.IsPostBack)
{
this.xmlObjectSearch.DataBind();
}
}
override protected void OnInit(EventArgs e)
{
InitializeComponent();
base.OnInit(e);
}
private void InitializeComponent()
{
this.Load += new System.EventHandler(this.Page_Load);
}
public override void Dispose()
{
base.Dispose ();
}
}
}
I just had a though about object modeling. I think that the problem is
mixing the View and Model in the way you are doing the stuff. Normally
the .net framework assumes that CreateChildControls is dealing with only
the view, not the model.
You are creating controls that a both the model and the view and assume that
only the first time that you are called you will be initializing your
control.
What you might do is completely separate the model from the view and perhaps
if you insist use a state machine approach to control the initialization.
I hope this helps