Andy Smith's Blog

Page.RegisterStartupScript('Andy', 'MetaBuilders_WebControls_GainKnowledge();');

The Composite Control Pattern

I've seen a a lot of people posting questions these days about composite controls. Most are having problems with viewstate. I thought I'd write up a simple example composite control so I can point at it. So here it is, a simple composite control that has a label and a textbox.

// Composite controls should derive from WebControl and implement INamingContainer
public class FooControl : WebControl, INamingContainer {
 // Override the getter for Controls with a call to EnsureChildControls.
 // This makes sure that your child controls always exist when they need to.
 public override ControlCollection Controls {
  get {
   EnsureChildControls();
   return base.Controls;
  }
 }
 // This is where you instantiate your child controls and set their default values.
 protected override void CreateChildControls() {
  Controls.Clear();
  myLabel = new Label();
  myLabel.ID = "myLabel";
  Controls.Add( myLabel );
  myTextBox = new TextBox();
  myTextBox.ID = "myTextBox";
  Controls.Add( myTextBox );
 }
 //These properties are delegated to the child controls.
 // As such, we call EnsureChildControls to make sure they are instantiated before accessing them.
 public String LabelText {
  get {
   EnsureChildControls();
   return myLabel.Text;
  }
  set {
   EnsureChildControls();
   myLabel.Text = value;
  }
 }
 public String TextBoxText {
  get {
   EnsureChildControls();
   return myTextBox.Text;
  }
  set {
   EnsureChildControls();
   myTextBox.Text = value;
  }
 }
 
 
 private Label myLabel;
 private TextBox myTextBox;
}

Comments

TrackBack said:

# March 10, 2004 6:10 PM

Confused said:

Andy,

Just wondering, if you were using this with more than one Label or TextBox control, would you suggest using arrays to hold them, or creating indiviual fields?
# March 25, 2004 3:35 PM

Rick O'Shay said:

This seems needlessly complicated and poorly documented. My controls are instantiated as class instance variables. They are available without having to call EnsureChildControls. They are plain old objects. They get added to the controls collection inside CreateChildControls, along with any configuration that needs to be done. I see no need for EnsureChildControls, but maybe I'm missing something?

# April 12, 2008 2:18 PM

Andy In Brum said:

Rick, I agree it is complicated and poorly documented. Having just stumbled across a problem, I think the reason why you need to call EnsureChildControls on the accessors is all about timing. If you don't call EnsureChildControls, the controls ARE added by CreateChildControls, but this doesnt happen until very late in the page execution lifecycle. In my case it was CreateChildControls was being called by the framework during the page's OnPreRender.

It may be you need your controls around earlier if they are to handle events that occur earlier in the lifecycle. Thus it is pragmatic to call EnsureChildControls. Yuk.

# December 9, 2008 5:26 AM
Leave a Comment

(required) 

(required) 

(optional)

(required)