ViewState of Contained Controls?

L

lisa

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
 
B

Brock Allen

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.
 
L

lisa

Brock said:
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
 
L

lisa

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
 
T

Teemu Keiski

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.
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,535
Members
45,007
Latest member
obedient dusk

Latest Threads

Top