CreateChildControls and Exception Failed to Load ViewState

C

Craig

Hi

I've been struggling with this problem for several days now, pretty much out
of ideas...

I have n number of xml files each defines what server side control to to
render inside my custom web control (composite). The OnInit of my web
control parses the xml files creating a collection of internal object
structures, like:
Report
ParmsCollection Parms get {...}

Parm
Control get {...}

In the OnInit, I assign the collection to the Session

Now for CreateChildControls, it looks something like this:

protected override void CreateChildControls() {
Controls.Clear();
DropDownList ddlReport = new DropDownList();
ddlReport.AutoPostback = true;
Controls.Add(ddlReport);

ArrayList reports = (ArrayList)Session["Reports"];

foreach(Report report in reports) {
ddlReport.Items.Add(report.Name);
}

Report report = reports[0];

// Now add the report controls
foreach(Parm parm in report.Parms) {
Controls.Add(parm.Control);
}
}

So the ddlReport drop down renders with the control(s) from the report
parameters. Now I select a different report from the drop down; this is
where everything goes to hell... I don't get the event from the ddlReport
control, when I hack something together making the selected report render it
controls, I end up with the Failed to load ViewState, needs to be re-created
the same way it was rendered.

Can anyonw help m out, this is frustrating me to bits.
 
W

Wilco Bauwer

I wouldn't store that stuff in the session, because its both not
necessary and not scalable.

As a rule of thumb, its often wiser to use a databound control for
representing a dynamic amount of controls. If you have a fixed number
of controls, you can create a CompositeControl and create those
controls in the CreateChildControls, etc.

That means that in your case, I would data bound the XML to for example
a Repeater. In the Repeater's template(s), you can create the
appropriate controls for each item in the data source. The Repeater
will make sure that the controls are recreated upon postback, etc. You
can do all this inside a composite control aswell, if you insist.

The reason you get this Failed to load ViewState exception, might have
to do with a difference in the control hierarchy before and after the
postback. I suggest you first specify the ID's of the controls, so that
a control has the same ID upon a postback. I also suggest that you
check when/by who CreateChildControls is actually called (e.g. check
the call stack). Also check the number of controls before and after the
postback.
 
C

Craig

Hi Wilco

Thanks for the reply. Firstly the session state was a temporary thing, I
think I'll end up caching the object model.

As far as the xml structure goes, it looks something like this:

<Report name='my report', description='my report description'>
<Parm name='parm1'>
<Control type='asp:TextBox' id='txtParm1' runat='server' text='report
text'/>
</Parm>
</Report>

The xml structure above represents a typical report file, there maybe
multiple <Parm> element, but only 1 <Control ... /> element for each <Parm>.
When the <Control> element is read, it uses ParseControl, assigning the
Control to Parm.Control property which is has a type of Control.

In the override CreateChildControls method I do this:

foreach(Parm parm in report.Parms) {
Controls.Add(parm.Control);
}

I'm not sure what to do on Postback, so I'm not sure what I am missing.
Given your advice on a Repeater, I'm not sure how this will be implemented
with the current xml structure.
 

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

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,483
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top