Immediate v. Delayed Delegation of Properties in CompositeControls

Discussion in 'ASP .Net Building Controls' started by Sky Sigal, Jun 29, 2005.

  1. Sky Sigal

    Sky Sigal Guest

    Hello:
    Going nuts looking for someone who can solve this riddle...

    ControlBuilder -- according to what I've seen -- parses attributes of
    declarative tags in alphabetic order, then parses nested tags in alphabetic
    order.

    And that is causing me a lot of trouble...

    Take for example the following control:

    <myControl>
    <Items>
    <ListItem>Uno</ListItem>
    <ListItem>Dos</ListItem>
    </Items>
    <Templates>
    <Main>
    ...insert here layout containinng one DropDownList that
    ...will be destination of above mentioned ListItems
    </Main>
    </Templates>
    </MyControl>

    In other words, the parser will process Items first, and if we follow
    Nikhil's suggested pattern of calling EnsureChildControls first, we will get
    an exception -- because TemplateMain is still null.
    If we provide a DefaultTemplate to fix this, we then end up with Items being
    processed, EnsureChildControls making a layout with the default template
    built into the control, then the parser parses Templates/Main, and resets
    ChildControlsCreated=false. ...So PreRender calls EnsureChildControls, which
    rebuilds the whole control with the new provided template...
    And the final mess is that we have the right template, but the drop down is
    empty because we threw away the original list of items.

    Yikes.

    Switch to Deffered Delegation, and make a IStateManaged ListItemCollection
    in the Container

    get {
    if (_Items==null){_Items = new ListItemCollection();
    if (this.TrackingViewState){((IStatemanager)_Items).TrackViewState();}
    return _Items;
    }
    and apply it later we have two choices -- that don't work.

    If we apply it in PrepareControlHierarchy, it's great...until
    postback...when we will always have a SelectedIndex of -1, because for the
    whole life of the control up to Render the inner listControl's list contains
    exactly 0 elements (they are still in the container's Items collection)...

    If we apply them in CreateChildControls, before adding the templatecontainer
    to the control, we end up with an Items property that is out of date...before
    CreateChildControls (CCC) it is the right list, but after CCC, the Items of
    importance are the innerList.Items... which we are not pointed at.



    So questions are:
    a) If Immediate delegation is used, how can ControlBuilder be taught in
    which order to process attributes? So that it sets up Template before it
    works on Items?
    b) If Delayed delegation used, how to set it up so that SelectedIndex is a
    property that works?
    c) If Delayed delegation -- how can it work with a nested gridview (ie no
    IStatemanager object to persist data in, so has to be handled in
    CreateChildControls as far as I can tell).


    Thanks very much,
    Sky
     
    Sky Sigal, Jun 29, 2005
    #1
    1. Advertising

  2. Sky Sigal

    Sky Sigal Guest

    Well, I'll be....!

    False alarm (sortof). The example below DOES work... With conditions...

    Turns out that for some unknown magic reason ControlBuilder parses ITemplate
    properties FIRST, then Attributes, then Complex properties, then bound
    properties...
    So this will work...

    The reason that I was not getting this result before, and thought that all
    hands should abandon ship, was because this is a simple example control: the
    control I was working on was more complex and had more templates going on, so
    I nested them one deeper in a dedicated class (clearer
    classification/ordering), giving the following tags instead:
    <MyControl>
    <Items>
    <ListItem>
    Uno, dos, tres..items to go...
    </ListItem>
    </Items>
    <Templates>
    <Main>
    ...same as before, define a ListBox where to dump Items mentioned
    above...
    </Main>
    <Header>
    ..you get the point...
    </Header>
    </Templates>
    </MyControl>

    So what was happening is that it is seeing 'Templates' as a Complex property
    -- and not as a Template -- so it processes Attributes, then Complex in
    alphabetic order, so Items before Templates...causing the lost data I was
    referring to.

    So duh. Works.

    Now. If only I could
    a) see why it is doing this -- moving Templates up to first position -- when
    I am looking at the code for ControlBuilder I could swear that it is doing
    attributes before complex before templates -- not templates before
    attributes...so I have no idea why I got so lucky. That naturally worries me
    to rely on something I don't understand.
    b) I have a property that I would like very much to move up to first
    position -- its an attribute called "ListControlType" (DropDown or ListBox),
    which I would like to be parsed prior to anything else...at the same time as
    Templates. But other than prefixing the name with a "_" to get it
    alphabetically first, I don't see how... Any other, cleaner, suggestions?

    Thank you,
    Sky Sigal


    --

    > Hello:
    > Going nuts looking for someone who can solve this riddle...
    >
    > ControlBuilder -- according to what I've seen -- parses attributes of
    > declarative tags in alphabetic order, then parses nested tags in alphabetic
    > order.
    >
    > And that is causing me a lot of trouble...
    >
    > Take for example the following control:
    >
    > <myControl>
    > <Items>
    > <ListItem>Uno</ListItem>
    > <ListItem>Dos</ListItem>
    > </Items>
    > <Templates>
    > <Main>
    > ...insert here layout containinng one DropDownList that
    > ...will be destination of above mentioned ListItems
    > </Main>
    > </Templates>
    > </MyControl>
    >
    > In other words, the parser will process Items first, and if we follow
    > Nikhil's suggested pattern of calling EnsureChildControls first, we will get
    > an exception -- because TemplateMain is still null.
    > If we provide a DefaultTemplate to fix this, we then end up with Items being
    > processed, EnsureChildControls making a layout with the default template
    > built into the control, then the parser parses Templates/Main, and resets
    > ChildControlsCreated=false. ...So PreRender calls EnsureChildControls, which
    > rebuilds the whole control with the new provided template...
    > And the final mess is that we have the right template, but the drop down is
    > empty because we threw away the original list of items.
    >
    > Yikes.
    >
    > Switch to Deffered Delegation, and make a IStateManaged ListItemCollection
    > in the Container
    >
    > get {
    > if (_Items==null){_Items = new ListItemCollection();
    > if (this.TrackingViewState){((IStatemanager)_Items).TrackViewState();}
    > return _Items;
    > }
    > and apply it later we have two choices -- that don't work.
    >
    > If we apply it in PrepareControlHierarchy, it's great...until
    > postback...when we will always have a SelectedIndex of -1, because for the
    > whole life of the control up to Render the inner listControl's list contains
    > exactly 0 elements (they are still in the container's Items collection)...
    >
    > If we apply them in CreateChildControls, before adding the templatecontainer
    > to the control, we end up with an Items property that is out of date...before
    > CreateChildControls (CCC) it is the right list, but after CCC, the Items of
    > importance are the innerList.Items... which we are not pointed at.
    >
    >
    >
    > So questions are:
    > a) If Immediate delegation is used, how can ControlBuilder be taught in
    > which order to process attributes? So that it sets up Template before it
    > works on Items?
    > b) If Delayed delegation used, how to set it up so that SelectedIndex is a
    > property that works?
    > c) If Delayed delegation -- how can it work with a nested gridview (ie no
    > IStatemanager object to persist data in, so has to be handled in
    > CreateChildControls as far as I can tell).
    >
    >
    > Thanks very much,
    > Sky
    >
    >
    >
    >
    >
    >
     
    Sky Sigal, Jul 1, 2005
    #2
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. =?Utf-8?B?Q2hyaXN0b3BoZSBQZWlsbGV0?=

    CompositeControls: ViewState properties w/ Mapped properties probl

    =?Utf-8?B?Q2hyaXN0b3BoZSBQZWlsbGV0?=, Jan 19, 2006, in forum: ASP .Net
    Replies:
    1
    Views:
    1,147
    Steven Cheng[MSFT]
    Jan 19, 2006
  2. Jeronimo Bertran

    CompositeControls not added to the toolbox

    Jeronimo Bertran, Apr 5, 2006, in forum: ASP .Net
    Replies:
    5
    Views:
    397
    Steven Cheng[MSFT]
    Apr 14, 2006
  3. matt
    Replies:
    1
    Views:
    407
  4. matt
    Replies:
    8
    Views:
    229
    Mauricio Fernández
    Jun 19, 2004
  5. Sam Roberts
    Replies:
    4
    Views:
    322
    Sam Roberts
    May 7, 2008
Loading...

Share This Page