I have a CompositeContro l with two types of properties:
1.) Mapped Properties that map directly to a child control's properties
(ex.: this.TextboxTex t = m_txt.Text). These properties are handled by their
underlying classes (such as the TextBox control), and are not persisted by me.
2.) Unique Properties that don't map directly and are persisted in ViewState
(ex.: this.LabelPosit ion, which specifies where on the form the label should
be rendered). These properties are applied to the relevant controls in
'OnPreRender()' , and sometimes used in 'CreateChildCon trols()'.
I can only get one of these types of properties to work properly at one
time. If, in the second type of property (those stored in ViewState) I add
the line 'ChildControlsC reated = false;' after the Set statement, the
ViewState properties work properly and render with their assigned values, but
then controls of the first type no longer work, and are always reset to their
initial values.
If I remove the 'ChildControlsC reate = false;' line from the ViewState
controls, the first type (Mapped Properties) function properly, including
maintaining their values on Postback, but the second type (Unique/ViewState
properties) always get set to their default values, even when they are
explicitly set in code or in the HTML markup.
The problem is that I need, obviously, both property types to work, but
after a lot of effort (and several forum posts), am no closer to a solution.
If you would like a full code sample of this, let me know and I'll email a
VS2005 solution to you.
Christophe
Type 1 (Mapped Properties) --> Generally defined in a child class that
inherits from a common parent
--------------------------
/// <summary>
/// Gets or sets the textbox text.
/// </summary>
/// <value>The textbox text.</value>
[Bindable(true)]
[Category("Textb ox")]
[DefaultValue(ty peof(string), "")]
[Description("Th e text that will be displayed in the textbox.")]
[Localizable(tru e)]
[NotifyParentPro perty(true)]
[RefreshProperti es(RefreshPrope rties.All)]
public string Text
{
get
{
EnsureChildCont rols();
return (m_txt.Text == null) ?
string.Empty :
m_txt.Text;
}
set
{
Debug.Assert(va lue != null, "Warning: TextboxText property is null!");
if (value != null)
{
EnsureChildCont rols();
m_txt.Text = value;
}
else
{
throw new NullReferenceEx ception("Textbo xText can not be
assigned a null value.");
}
}
}
Type 2 (Unique Properties) --> Defined in a parent class that contains all
common elements
--------------------------
/// <summary>
/// Gets or sets the position of the descriptive label relative to the rest
of the control.
/// </summary>
/// <value>The label position.</value>
[Bindable(true)]
[Category("Label ")]
[DefaultValue(Po sition.Left)]
[Localizable(fal se)]
[Description("Th e position of the descriptive label relative to the rest of
the control.")]
public Position LabelPosition
{
get
{
Position p = (Position)ViewS tate["LabelPosit ion"];
return p;
}
set
{
ViewState["LabelPosit ion"] = value;
// Toggle line to see effect
// ChildcontrolsCr eate = false;
}
}
CreateChildCont rols() -> Code from parent class, SupportFormLabe lledControl
(which handles all common elements)
---------------------
protected override void CreateChildCont rols()
{
// Clear the control collection
Controls.Clear( );
// Any dependant controls used in this custom control must
// be added to the control 'hierarchy'. If they are not added
// to the control collection, they will not be visible to other
// controls on the page.
// Instantiate any dependant controls
m_tbl = new Table();
m_lbl = new CallbackLabel() ;
m_icn = new IconPopupContro l();
m_plc = new PlaceHolder();
// Create table object and format it through relevant method
m_tbl = SharedFunctions .CreateLabelled ControlTable(th is.LabelPositio n);
// Add table to the control collection
Controls.Add(m_ tbl);
// Add controls to the table control collection
switch (this.LabelPosi tion)
{
case Position.Left:
m_tbl.Rows[0].Cells[0].Controls.Add(m _lbl);
m_tbl.Rows[0].Cells[1].Controls.Add(m _plc);
m_tbl.Rows[0].Cells[1].Controls.Add(m _icn);
// Set relevant design properties
m_tbl.Rows[0].Cells[0].Width = new
Unit(this.Label Width.ToString( ));
m_tbl.Rows[0].Cells[0].VerticalAlign = this.LabelVerti calAlign;
break;
case Position.Top:
m_tbl.Rows[0].Cells[0].Controls.Add(m _lbl);
m_tbl.Rows[1].Cells[0].Controls.Add(m _plc);
m_tbl.Rows[1].Cells[0].Controls.Add(m _icn);
// Set relevant design properties
m_tbl.Rows[0].Cells[0].Width = new
Unit(this.Label Width.ToString( ));
m_tbl.Rows[0].Cells[0].VerticalAlign = this.LabelVerti calAlign;
break;
case Position.Right:
m_tbl.Rows[0].Cells[0].Controls.Add(m _plc);
m_tbl.Rows[0].Cells[0].Controls.Add(m _icn);
m_tbl.Rows[0].Cells[1].Controls.Add(m _lbl);
// Set relevant design properties
m_tbl.Rows[0].Cells[1].Width = new
Unit(this.Label Width.ToString( ));
m_tbl.Rows[0].Cells[1].VerticalAlign = this.LabelVerti calAlign;
break;
case Position.Bottom :
m_tbl.Rows[0].Cells[0].Controls.Add(m _plc);
m_tbl.Rows[0].Cells[0].Controls.Add(m _icn);
m_tbl.Rows[1].Cells[0].Controls.Add(m _lbl);
// Set relevant design properties
m_tbl.Rows[1].Cells[0].Width = new
Unit(this.Label Width.ToString( ));
m_tbl.Rows[1].Cells[0].VerticalAlign = this.LabelVerti calAlign;
break;
default:
Debug.Assert(fa lse);
break;
}
// Call base method
base.CreateChil dControls();
}
CreateChildCont rols() -> Code from inheriting class, which specializes the
top-level class (i.e., SupportTextBox)
---------------------
protected override void CreateChildCont rols()
{
// Call base method (create the underlying table and common controls)
base.CreateChil dControls();
// Instantiate any dependant controls
m_txt = new CallbackTextBox ();
// Register any events associated with dependant controls
m_txt.TextChang ed += new EventHandler(Ra iseTextChanged) ;
m_icn.ImageMous eDown += new EventHandler(th is.RaiseIconMou seDown);
// Add unique controls to the base class placeholder
m_plc.Controls. Add(m_txt);
}
OnPreRender() --> Parent Class (SupportFormLab elledControl)
-------------
contains the event data.</param>
protected override void OnPreRender(Eve ntArgs e)
{
// Call base method
base.OnPreRende r(e);
// Add reference to embedded CSS file
if (!(Page == null))
{
if (!(Page.ClientS cript.IsClientS criptBlockRegis tered("CssStyle s")))
{
string cssLocation = this.Page.Clien tScript.GetWebR esourceUrl(
this.GetType(),
"CompanyName.EE E.Web.UI.Resour ces.Styles.css" );
string cssLink = @"<!-- Css Stylesheet -->" + "\r\n";
cssLink += @"<link href='" + cssLocation + "' rel='stylesheet '
type='text/css' />" + "\r\n";
Page.ClientScri pt.RegisterClie ntScriptBlock(
typeof(SupportF ormLabelledCont rol),
"CssStyles" ,
cssLink);
}
}
// Associate dependent control properties with this control's properties
m_lbl.CssClass = this.LabelCssCl ass;
m_lbl.Text = this.LabelText;
m_lbl.Visible = this.LabelVisib le;
m_lbl.RadContro lsDir = this.ScriptsPat h;
m_lbl.CallbackE nabled = this.CallbackEn abled;
m_lbl.DisableAt Callback = this.DisableAtC allback;
m_lbl.Enabled = this.Enabled;
m_icn.CallbackE nabled = this.CallbackEn abled;
m_icn.DisableAt Callback = this.DisableAtC allback;
m_icn.WarningIm ageUrl = this.WarningIma geUrl;
m_icn.ImageAlig n = this.ImageAlign ;
m_icn.EmptyImag eUrl = this.EmptyImage Url;
m_icn.MessageSt yle = this.MessageSty le;
m_icn.PopupText = this.PopupText;
m_icn.PopupText ResourceKey = this.PopupTextR esourceKey;
m_icn.PopupTitl e = this.PopupTitle ;
m_icn.PopupTitl eResourceKey = this.PopupTitle ResourceKey;
m_icn.LinkUrl = this.LinkUrl;
m_icn.Enabled = this.Enabled;
m_icn.CssClass = this.WarningIco nCssStyle;
// Enable or disable warning icon as appropriate
m_icn.Visible = this.Required ? true : false;
}
OnPreRender() --> Specialized, Inheriting Class (SupportTextBox )
-------------
protected override void OnPreRender(Eve ntArgs e)
{
// Call base method (common fields like m_lbl and m_icn are handled here)
base.OnPreRende r(e);
// Associate dependent control properties with this control's properties
m_txt.MaxLength = this.MaxLength;
m_txt.ReadOnly = this.ReadOnly;
m_txt.RadContro lsDir = this.ScriptsPat h;
m_txt.DisableAt Callback = this.DisableAtC allback;
m_txt.CallbackE nabled = this.CallbackEn abled;
m_txt.CssClass = this.TextboxCss Class;
m_txt.Enabled = this.Enabled;
m_txt.Text = this.Text;
m_txt.TextMode = this.TextMode;
m_txt.Width = this.TextboxWid th;
m_txt.Rows = this.Rows;
}