RecreateChildControls and a new solution instead of it

look this question:
Say you are developing the simples compositcontrol : a wrapper around a textbox (the composite control only has a child control, which is the TextBox). The composite control has only one property: Text. This property retrieves and sets the value of the text property of the inner TextBox control .

now,you will face a strange problem: the property window shows the composite control property, but it doesn't show it's value. for instance, if you go there and set the property, the control isn't rendered correctly (it only shows an empty texbox) and the property window remains empty.

how to explain and solve it?

RecreateChildControls

Server controls implement ICompositeControlDesignerAccessor interface to allow visual designers such as Visual Studio 2005/2008 to recreate their control. When you change the property of a server control in the VS Property window, under the hood VS calls the RecreateChildControls method of the control to recreate its child controls.
If you derive your custom control from the CompositeControl base class, you don't have to worry about implementing the ICompositeControlDesignerAccessor interface because the base class has already implemented it. Let's take a look under the hood of the CompositeControl class's implementation of the RecreateChildControls method:

 1 public abstract class CompositeControl : WebControl, INamingContainer, ICompositeControlDesignerAccessor
 2 {
 3   void ICompositeControlDesignerAccessor.RecreateChildCon trols()
 4   {
 5     this.RecreateChildControls();
 6   }
 7 
 8   protected virtual void RecreateChildControls()
 9   {
10     base.ChildControlsCreated = false;
11     this.EnsureChildControls();
12   }
13 }

As we can see, the RecreateChildControls method first sets the ChildControlsCreated property to false and then calls the EnsureChildControls method, which in turn calls the CreateChildControls method.

Recall that the CreateChildControls method of a composite control first calls the Clear() method to remove all the child controls from the Controls collection of the composite control, which means that all the property values of the child controls are lost forever. That is the reason for the design-time misbehavior.

solution 1:RecreateChildControls
The simple solution is to override the CompositeControl's RecreateChildControls() function. take a look:

1 protected override void RecreateChildControls()
2 {
3  if (this.ChildControlsCreated == false)
4  {
5   base.RecreateChildControls();
6  }
7 

in fact,  I found this code inside the Microsoft's Composite Web Control Example (http://msdn2.microsoft.com/en-us/library/3257x3ea.aspx).  but Without any explanation.

solution 2:Just modify the properties of the composite control to use private fields as backing store.
Here is an example:

 1         private string __temp = "";
 2         [Category("dern")]
 3         [Description("value information")]
 4         public string tbValue
 5         {
 6             get
 7             {
 8                 if (this.DesignMode)
 9                 {
10                     return __temp;
11                 }
12                 this.EnsureChildControls();
13                 return tb.Text;
14             }
15             set
16             {
17                 if (this.DesignMode)
18                 {
19                     __temp = value;
20                     return;
21                 }
22                 this.EnsureChildControls();
23                 tb.Text = value;
24             }
25         }

then assign the values of the properties of the composite control to the properties of the associated child controls. For example:

 1         protected override void CreateChildControls()
 2         {
 3             if (this.ChildControlsCreated == false)
 4             {
 5                 this.Controls.Clear();
 6 
 7                 tb = new TextBox();
 8                 tb.ID = "txtID";
 9                 tb.Text = __temp;
10                 this.Controls.Add(tb);
11 
12                 this.ChildControlsCreated = true;
13             }
14         }

end!

posted on 2009-09-16 15:46  武汉虫虫  阅读(327)  评论(0编辑  收藏  举报

导航