LA.NET [EN]

Apr 12

In one of my last posts, I talked about an unexpected behavior that I was facing when trying to port an old ASP.NET composite server control to ASP.NET 2.0. As you recall, in ASP.NET 2.0, composite controls should inherit from CompositeControl (and by doing this, your control will automatically get a composite designer – an instance of the CompositeControlDesigner class, to be more precise). The problem here is that the designer recreates your control hierarchy when you change a property on the designer, leaving you with an empty property grid and with the “wrong” HTML presented on the designer surface.

At first, this seems like an odd thing to do and I really didn”t understand why the designer behaved like that…Since nobody replied to my previous post (and since I”m really stubborn), I”ve spent a few hours trying to study the new composite controls (again, thanks Lutz! you”re my hero! 🙂 ,,).  It looks like (now – ie, in ASP.NET 2.0) you”re supposed to  save all your control properties in view state (even when these properties are just proxies to your internal controls” properties) and then you should disable the viewstate of the child controls after their creation (which is done in the CreateChildControls). This is a new pattern and I”ve never seen it being followed in ASP.NET 1.1 (at least, I didn”t used it in any of my custom server controls). Though I didn”t find anything in the docs, it seems like most (if not all) of the “default” composite controls follow this approach.

On the other hand, you can still use the old 1.1 pattern of using “property proxies” to the inner control properties. If you want to follow this approach, you only need to override the virtual RecreateChildControls method so that it doesn”t recreate the internal control hierarchy when you change a property on the designer.

After all, there was some logic in the “madness” of recreating the internal child controls of a composite control when you change its properties on the designer…

3 comments so far

  1. Cyril
    1:14 pm - 4-22-2007

    I see the same things with Reflector, .net 2.0 controls manage their own viewstate, they don”t use childs controls” viewstate. I found this pattern very stupid, I prefer the “proxy” method.

    But with the proxy method, where do we have to call the EnsureChildControls() method ? we have 2 solutions on the constructor or on each properties accessor which is very boring. If we call the EnsureChildControls() on the constructor the designer is firing an error because we can”t modifiy the controls collection on the constructor. The DesignMode property isn”t yet set so we have to test the validity of HttpContext.Current in our control constructor.

    If you have an another solution i”m listening to you 🙂

  2. Luis Abreu
    8:57 am - 4-23-2007

    hello Cyril.

    Well, I”m following the ASP.NET 1.X recommendations: i”m calling ensurechildcontrols on all the properties. Since I”m inheriting from compositecontrol, the controls property is already implemented correctly by that base class (ie, it already calls ensurechildcontrols before calling the base class property).

  3. JT
    7:56 am - 1-13-2008

    I found this post after running into similar issues with the CompositeControlDesigner.

    I found a simple solution in the Microsoft”s Composite Web Control example (http://msdn2.microsoft.com/en-us/library/3257x3ea.aspx). The solution is to override the CompositeControl”s RecreateChildControls() function. The function should look like:

    protected override void RecreateChildControls()
    {
    EnsureChildControls();
    }

    To understand why this fixes the issue, take a look at the CompositeControlDesigner”s CreateChildControl() function.