ViewState of Contained Controls?

Discussion in 'ASP .Net Building Controls' started by lisa@starways.net, May 2, 2005.

  1. Guest

    I've built my tab control, and it works great. Except for one problem.
    Any controls which are contained in any of the tabs lose state. The
    tab control itself retains state. Any content added does not.

    I tried putting a checkbox control inside of one of the tabs and
    outside of the tab control. I checked them both in run time and then
    triggered a postback. The checkbox outside of the tab control was
    still checked. The checkbox inside the tab control was not.

    I tried adding this to OnInit:

    For Each myTab As Tab In Tabs
    For Each myControl As Control In myTab.Controls
    myControl.TrackViewState()
    Next
    Next

    This was the result:

    'System.Web.UI.Control.Protected Overridable Sub TrackViewState()' is
    not accessible in this context because it is 'Protected'.

    I have ViewStateEnabled set explicitly to True on both checkboxes. Is
    there anything I can do to get the content to retain state?

    Thanks,
    Lisa
    , May 2, 2005
    #1
    1. Advertising

  2. Brock Allen Guest

    Two things:

    1) The contained controls are added dynamically, I presume? When are they
    added? You need to make sure those get recreadted upon postback every time.
    It woulds like you've got this part figured out.

    2) When are you adding the properties/data to the controls? If you set the
    properties in or prior to the control's Init the controls assume that data
    is static and we be set again on every postback. If you want to dynamically
    add properties such that it survives postback you need to add this after
    the control's Init event. I say the control's init event, not the page's
    because you could be dynamically adding these after the page's init has fired.
    The distinction is when you add the control into the server side control
    tree. If you set the property then add the control, then from the control's
    perspective Init has not yet been called. If you add the control to the control
    tree then set a property the control's init will have been fired. It's a
    subtle code ordering which causes different behavior.

    -Brock
    DevelopMentor
    http://staff.develop.com/ballen



    > I've built my tab control, and it works great. Except for one
    > problem.
    > Any controls which are contained in any of the tabs lose state. The
    > tab control itself retains state. Any content added does not.
    > I tried putting a checkbox control inside of one of the tabs and
    > outside of the tab control. I checked them both in run time and then
    > triggered a postback. The checkbox outside of the tab control was
    > still checked. The checkbox inside the tab control was not.
    >
    > I tried adding this to OnInit:
    >
    > For Each myTab As Tab In Tabs
    > For Each myControl As Control In myTab.Controls
    > myControl.TrackViewState()
    > Next
    > Next
    > This was the result:
    >
    > 'System.Web.UI.Control.Protected Overridable Sub TrackViewState()' is
    > not accessible in this context because it is 'Protected'.
    >
    > I have ViewStateEnabled set explicitly to True on both checkboxes. Is
    > there anything I can do to get the content to retain state?
    >
    > Thanks,
    > Lisa
    Brock Allen, May 2, 2005
    #2
    1. Advertising

  3. Guest

    Brock Allen wrote:
    > Two things:
    >
    > 1) The contained controls are added dynamically, I presume? When are

    they
    > added? You need to make sure those get recreadted upon postback every

    time.
    > It woulds like you've got this part figured out.


    The contained controls can be added by going into HTML view and adding
    them between the tab tags:

    <fw:TabStrip id="TabStrip7" runat="server">
    <fw:Tab Text="Tab 1" ID="TabStrip7__ctl0">&nbsp;</fw:Tab>
    <fw:Tab Text="Tab 2" ID="TabStrip7__ctl1">&nbsp;</fw:Tab>
    <fw:Tab Text="Tab 3" ID="TabStrip7__ctl2">
    <asp:CheckBox runat="server" ID="CheckBox1" Text="testme" />
    </fw:Tab>
    <fw:Tab Text="Tab 4" ID="TabStrip7__ctl3">&nbsp;</fw:Tab>
    </fw:tabstrip>

    I added CheckBox1 into TabStrip7__ct12 (Tab 3). I could have done the
    same thing programmatically, by doing
    TabStrip7.Tabs(2).Controls.Add(CheckBox1).

    > 2) When are you adding the properties/data to the controls? If you

    set the
    > properties in or prior to the control's Init the controls assume that

    data
    > is static and we be set again on every postback.


    Ouch. And that seems to be exactly what's happening.

    > If you want to dynamically
    > add properties such that it survives postback you need to add this

    after
    > the control's Init event. I say the control's init event, not the

    page's
    > because you could be dynamically adding these after the page's init

    has fired.
    > The distinction is when you add the control into the server side

    control
    > tree. If you set the property then add the control, then from the

    control's
    > perspective Init has not yet been called. If you add the control to

    the control
    > tree then set a property the control's init will have been fired.

    It's a
    > subtle code ordering which causes different behavior.


    I think I understand what you're saying, but I'm not sure how to fix
    the problem. The way it sounds, my Tab 3 is recreating its child
    CheckBox1 exactly as it was initially created, and no ViewState is
    being applied to CheckBox1. Do I need to do something complex with
    ViewState in order to save the state of CheckBox1 (or whatever child
    controls there may be in each of the tabs)? Is there no way to access
    the child controls' internal ViewState and apply it?

    Thanks for your help. I'm so close here that I can taste it.

    Lisa


    >
    > -Brock
    > DevelopMentor
    > http://staff.develop.com/ballen
    >
    >
    >
    > > I've built my tab control, and it works great. Except for one
    > > problem.
    > > Any controls which are contained in any of the tabs lose state.

    The
    > > tab control itself retains state. Any content added does not.
    > > I tried putting a checkbox control inside of one of the tabs and
    > > outside of the tab control. I checked them both in run time and

    then
    > > triggered a postback. The checkbox outside of the tab control was
    > > still checked. The checkbox inside the tab control was not.
    > >
    > > I tried adding this to OnInit:
    > >
    > > For Each myTab As Tab In Tabs
    > > For Each myControl As Control In myTab.Controls
    > > myControl.TrackViewState()
    > > Next
    > > Next
    > > This was the result:
    > >
    > > 'System.Web.UI.Control.Protected Overridable Sub TrackViewState()'

    is
    > > not accessible in this context because it is 'Protected'.
    > >
    > > I have ViewStateEnabled set explicitly to True on both checkboxes.

    Is
    > > there anything I can do to get the content to retain state?
    > >
    > > Thanks,
    > > Lisa
    , May 2, 2005
    #3
  4. Guest

    I've waded through Microsoft's source code for their MultiPage control
    (an unpleasant experience), because I know that control persists the
    state of its contents. But for the life of me, I cannot see why theirs
    does and mine doesn't.

    My TabStrip control contains a TabCollection which is made up of Tab
    controls. Tab controls inherit from WebControl. Initially, I was
    inheriting from Control, but I thought maybe changing it to WebControl
    would help. It didn't.

    Since it's inheriting from WebControl, it already has a Controls
    collection. For some reason, I can't access Tab.RenderChildren from
    the TabStrip Render function (it says because it's Protected), so I'm
    looping through Tab.Controls and rendering each one in series. And
    that works. It's just that it's rendering the intial state of the
    content, and not any changed state.

    Does anyone have any ideas?

    TIA,
    Lisa


    wrote:
    > Brock Allen wrote:
    > > Two things:
    > >
    > > 1) The contained controls are added dynamically, I presume? When

    are
    > they
    > > added? You need to make sure those get recreadted upon postback

    every
    > time.
    > > It woulds like you've got this part figured out.

    >
    > The contained controls can be added by going into HTML view and

    adding
    > them between the tab tags:
    >
    > <fw:TabStrip id="TabStrip7" runat="server">
    > <fw:Tab Text="Tab 1" ID="TabStrip7__ctl0">&nbsp;</fw:Tab>
    > <fw:Tab Text="Tab 2" ID="TabStrip7__ctl1">&nbsp;</fw:Tab>
    > <fw:Tab Text="Tab 3" ID="TabStrip7__ctl2">
    > <asp:CheckBox runat="server" ID="CheckBox1" Text="testme" />
    > </fw:Tab>
    > <fw:Tab Text="Tab 4" ID="TabStrip7__ctl3">&nbsp;</fw:Tab>
    > </fw:tabstrip>
    >
    > I added CheckBox1 into TabStrip7__ct12 (Tab 3). I could have done

    the
    > same thing programmatically, by doing
    > TabStrip7.Tabs(2).Controls.Add(CheckBox1).
    >
    > > 2) When are you adding the properties/data to the controls? If you

    > set the
    > > properties in or prior to the control's Init the controls assume

    that
    > data
    > > is static and we be set again on every postback.

    >
    > Ouch. And that seems to be exactly what's happening.
    >
    > > If you want to dynamically
    > > add properties such that it survives postback you need to add this

    > after
    > > the control's Init event. I say the control's init event, not the

    > page's
    > > because you could be dynamically adding these after the page's init

    > has fired.
    > > The distinction is when you add the control into the server side

    > control
    > > tree. If you set the property then add the control, then from the

    > control's
    > > perspective Init has not yet been called. If you add the control to

    > the control
    > > tree then set a property the control's init will have been fired.

    > It's a
    > > subtle code ordering which causes different behavior.

    >
    > I think I understand what you're saying, but I'm not sure how to fix
    > the problem. The way it sounds, my Tab 3 is recreating its child
    > CheckBox1 exactly as it was initially created, and no ViewState is
    > being applied to CheckBox1. Do I need to do something complex with
    > ViewState in order to save the state of CheckBox1 (or whatever child
    > controls there may be in each of the tabs)? Is there no way to

    access
    > the child controls' internal ViewState and apply it?
    >
    > Thanks for your help. I'm so close here that I can taste it.
    >
    > Lisa
    >
    >
    > >
    > > -Brock
    > > DevelopMentor
    > > http://staff.develop.com/ballen
    > >
    > >
    > >
    > > > I've built my tab control, and it works great. Except for one
    > > > problem.
    > > > Any controls which are contained in any of the tabs lose state.

    > The
    > > > tab control itself retains state. Any content added does not.
    > > > I tried putting a checkbox control inside of one of the tabs and
    > > > outside of the tab control. I checked them both in run time and

    > then
    > > > triggered a postback. The checkbox outside of the tab control

    was
    > > > still checked. The checkbox inside the tab control was not.
    > > >
    > > > I tried adding this to OnInit:
    > > >
    > > > For Each myTab As Tab In Tabs
    > > > For Each myControl As Control In myTab.Controls
    > > > myControl.TrackViewState()
    > > > Next
    > > > Next
    > > > This was the result:
    > > >
    > > > 'System.Web.UI.Control.Protected Overridable Sub

    TrackViewState()'
    > is
    > > > not accessible in this context because it is 'Protected'.
    > > >
    > > > I have ViewStateEnabled set explicitly to True on both

    checkboxes.
    > Is
    > > > there anything I can do to get the content to retain state?
    > > >
    > > > Thanks,
    > > > Lisa
    , May 3, 2005
    #4
  5. Teemu Keiski Guest

    Even though Scott says in that article that dynamical controls should be
    recreated in Page_Init, that's not always true or must thing to do.

    If you see his ViewState article:
    http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnaspp/html/viewstate.asp
    there is said:

    Note You may be able to get away with loading your controls in the
    Page_Load event handler and maintaining the view state properly. It all
    depends on whether or not you are setting any properties of the dynamically
    loaded controls programmatically and, if so, when you're doing it relative
    to the Controls.Add(dynamicControl) line. A thorough discussion of this is a
    bit beyond the scope of this article, but the reason it may work is because
    the Controls property's Add() method recursively loads the parent's view
    state into its children, even though the load view state stage has passed.

    And yes, it is so. You can also add them in Page_Load, it's just that
    dynamic controls dealing with postback data, if they are added in Load, they
    get their postback data loaded *after* Load event (2nd postback data
    loading), and those added before Load, get their postback data loaded before
    Page_Load. Postback data loading is more the thing impacting this, than
    anything else.

    --
    Teemu Keiski
    ASP.NET MVP, AspInsider
    Finland, EU
    http://blogs.aspadvice.com/joteke

    "bmwbzz" <> wrote in message
    news:...
    >
    > When are you creating the controls? You must re-create the controls in
    > the page_init event EVERY time the page postbacks in order to have the
    > viewstate set correctly.
    >
    > look at this article about dyanmic controls and the page lifecycle:
    >
    > http://aspnet.4guysfromrolla.com/articles/081402-1.aspx
    >
    > hope that helps.
    >
    >
    >
    > --
    > bmwbzz
    > ------------------------------------------------------------------------
    > Posted via http://www.codecomments.com
    > ------------------------------------------------------------------------
    >
    Teemu Keiski, Dec 14, 2005
    #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. Paul
    Replies:
    0
    Views:
    305
  2. John
    Replies:
    2
    Views:
    451
    William F. Robertson, Jr.
    Jul 2, 2003
  3. starwiz
    Replies:
    4
    Views:
    2,224
    starwiz
    Feb 6, 2005
  4. Willy
    Replies:
    2
    Views:
    539
    Karl Seguin
    Dec 21, 2004
  5. Warped
    Replies:
    2
    Views:
    502
    Warped
    Jul 15, 2005
Loading...

Share This Page