Complex control lifecycle issue

Discussion in 'ASP .Net Building Controls' started by Iain, Jun 16, 2004.

  1. Iain

    Iain Guest

    I've built a control whose purpose is to render a shopping cart based on
    templates and an Order object which gets passed to it.

    I'm keeping the order object in the Session object and therefore have no
    need to use ViewState for this control. Instead I create the ChildControls
    based on what is in the Order (passed in during initialisation) and
    databinding with the various templates in the page.

    This seems to work fine (though there has been a certain amount of
    frustration in the learning curve!).

    What I want to do now is to add buttons into the templates which will cause
    (say) an order line to be deleted. I want to take care of this in the
    rendering control - I see no need to pass this up to the page it sits in.

    So I've added the buttons into the template and caught the bubble as it
    comes up. Then I make the changes (E.g. delete a line item) on the order
    object.

    This seemed to work the NEXT time I did something.

    It turns out the issue (sorry about dribbling on here, but it is quite
    complex!) is when things are made.

    The CreateChildControls is called BEFORE the event handling / bubbling
    happens. So in this instance I create my UI with the original order and
    then modify the order to remove a line item. Of course the UI (in terms of
    the control hierarchy) is already there so the removal has no effect until
    the NEXT event.

    I tried moving the creation of the control hierarchy (into render), but then
    there were no controls to raise the event against.

    Finally, I did both. I created the control hiearchy in CreateChildControls
    and then deleted it and recreated it in Render.

    This seems to work, but I can't help thinking, a) it's a horrid way to do
    this and b) surely something will go wrong.

    Can anyone suggest a better way of doing this (parsing the control tree to
    remove the specific elements that are implicitly deleted is not really an
    option. I don't think ... hmmm.)?

    Or confirm that this is safe?

    Thanks


    Iain
     
    Iain, Jun 16, 2004
    #1
    1. Advertising

  2. Hi Iain,

    In a postback its okay to a) re-construct the previously created control
    tree and then, after handling an event or so, b) re-create the control tree
    to reflect the new changes before the control gets rendered. This may sounds
    weird at first, but its a totally valid approach. a) is necessary in order
    for state and events to work properly, then after an event has been fired
    there is nothing wrong in maybe updating some of your control's properties
    (let's say OrderLineCount) and recreate the children to reflect this change.

    Just keep in mind that children should *always* be created in the
    CreateChildControls method (never in Render as you may be suggesting in your
    message).

    Also, when you modify a property that should cause a recreation of child
    controls make sure you add a call to base.ChildControlsCreated = false but
    do not call CreateChildControls yourself, i.e.:

    public int OrderLineCount {
    set {
    _orderLineCount = value;
    // with the following you make sure a recreation of children (when
    needed) using the new updated value
    base.ChildControlsCreated = false;
    }
    }

    Let me know if things look clear now,

    --
    Victor Garcia Aprea
    Microsoft MVP | ASP.NET
    Looking for insights on ASP.NET? Read my blog:
    http://obies.com/vga/blog.aspx



    "Iain" <> wrote in message
    news:%23OmBgI$...
    > I've built a control whose purpose is to render a shopping cart based on
    > templates and an Order object which gets passed to it.
    >
    > I'm keeping the order object in the Session object and therefore have no
    > need to use ViewState for this control. Instead I create the

    ChildControls
    > based on what is in the Order (passed in during initialisation) and
    > databinding with the various templates in the page.
    >
    > This seems to work fine (though there has been a certain amount of
    > frustration in the learning curve!).
    >
    > What I want to do now is to add buttons into the templates which will

    cause
    > (say) an order line to be deleted. I want to take care of this in the
    > rendering control - I see no need to pass this up to the page it sits in.
    >
    > So I've added the buttons into the template and caught the bubble as it
    > comes up. Then I make the changes (E.g. delete a line item) on the order
    > object.
    >
    > This seemed to work the NEXT time I did something.
    >
    > It turns out the issue (sorry about dribbling on here, but it is quite
    > complex!) is when things are made.
    >
    > The CreateChildControls is called BEFORE the event handling / bubbling
    > happens. So in this instance I create my UI with the original order and
    > then modify the order to remove a line item. Of course the UI (in terms

    of
    > the control hierarchy) is already there so the removal has no effect until
    > the NEXT event.
    >
    > I tried moving the creation of the control hierarchy (into render), but

    then
    > there were no controls to raise the event against.
    >
    > Finally, I did both. I created the control hiearchy in

    CreateChildControls
    > and then deleted it and recreated it in Render.
    >
    > This seems to work, but I can't help thinking, a) it's a horrid way to do
    > this and b) surely something will go wrong.
    >
    > Can anyone suggest a better way of doing this (parsing the control tree to
    > remove the specific elements that are implicitly deleted is not really an
    > option. I don't think ... hmmm.)?
    >
    > Or confirm that this is safe?
    >
    > Thanks
    >
    >
    > Iain
    >
    >
     
    Victor Garcia Aprea [MVP], Jun 17, 2004
    #2
    1. Advertising

  3. Iain

    Iain Guest

    Thanks Victor.

    So, to summarise this approach makes sense but I should be careful of the
    details.

    Specifically, I should set

    >>base.ChildControlsCreated = false;


    whenever I do something in an event that may affect the hierarchy.

    What I wasn't clear on is when I should recreate the hierarchy?

    Specifically, will the framework call CreateChildControls at an opportune
    time automatically (before Render) or do I need to do a check at some point
    (OnPreRender or Render?) and recreated them as needed?

    Thanks again - sometimes you've done something 'right', but you can't quite
    believe it!


    Iain

    "Victor Garcia Aprea [MVP]" <> wrote in message
    news:...
    > Hi Iain,
    >
     
    Iain, Jun 17, 2004
    #3
  4. You don't need to explicity create the children, the framework will do that
    automatically when they are needed, i.e. before rendering, or earlier if a
    child need to load state or fire an event.

    One situation you need to be aware of that the framework is not currently
    covering is when you access a child by index, i.e:

    [C#]
    Control ctrl = Controls[3];

    if when this code runs children were not yet created (because of any of the
    previous considered reasons, i.e.: rendering,etc) then they WONT be
    automatically created. So you're required to call base.EnsureChildControls
    before accesing the Controls collection by index. A much better solution
    would be to override the get accesor for the Controls property of your
    composite control and call EnsureChildControls in there, i.e:

    [C#]
    public override ControlCollection Controls {
    get {
    base.EnsureChildControls ();
    return base.Controls;
    }
    }

    The next version of ASP.NET will include the scenario missing from the v1.x
    bits by introducing a new CompositeControl base class that would do exactly
    the same check in the Controls property get accesor as I described above.

    Good luck with your custom control development!

    --
    Victor Garcia Aprea
    Microsoft MVP | ASP.NET
    Looking for insights on ASP.NET? Read my blog:
    http://obies.com/vga/blog.aspx





    "Iain" <> wrote in message
    news:%...
    > Thanks Victor.
    >
    > So, to summarise this approach makes sense but I should be careful of the
    > details.
    >
    > Specifically, I should set
    >
    > >>base.ChildControlsCreated = false;

    >
    > whenever I do something in an event that may affect the hierarchy.
    >
    > What I wasn't clear on is when I should recreate the hierarchy?
    >
    > Specifically, will the framework call CreateChildControls at an opportune
    > time automatically (before Render) or do I need to do a check at some

    point
    > (OnPreRender or Render?) and recreated them as needed?
    >
    > Thanks again - sometimes you've done something 'right', but you can't

    quite
    > believe it!
    >
    >
    > Iain
    >
    > "Victor Garcia Aprea [MVP]" <> wrote in message
    > news:...
    > > Hi Iain,
    > >

    >
    >
     
    Victor Garcia Aprea [MVP], Jun 18, 2004
    #4
  5. Iain

    Iain Guest

    Victor. Many thanks for your help!

    Iain
     
    Iain, Jun 18, 2004
    #5
    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. John Lau

    Page and control lifecycle

    John Lau, May 11, 2004, in forum: ASP .Net
    Replies:
    2
    Views:
    531
    John Lau
    May 11, 2004
  2. Weston Weems

    Page LifeCycle kinda complex

    Weston Weems, Aug 10, 2004, in forum: ASP .Net
    Replies:
    0
    Views:
    413
    Weston Weems
    Aug 10, 2004
  3. Helen
    Replies:
    0
    Views:
    355
    Helen
    Oct 25, 2004
  4. Frankie
    Replies:
    2
    Views:
    5,995
    Frankie
    Jun 23, 2005
  5. Sky
    Replies:
    7
    Views:
    650
Loading...

Share This Page