Composite Web Control and Dynamically Created Children Controls.

C

Craig

Hi

I am developing a web control which creates other web controls. During the
OnInit of the my web control I read an Xml file which tells my web control
which child control to create, adding the child controls into a private
collection.

In the CreateChildControls (override) method, I loop through my collection
of child controls, adding them to the web control:
this.Controls.Add(this.Page.ParseControl(childControlCol));

I do not expose any properties of child controls in the web control.

Everything to this point renders as expected to the page. Say for example I
render a TextBox child control from my collection. The user enters a value,
then does a post back. How can I access the value of the TextBox control.
Normally I would do this.Controls[childControlId] or a this.FindControl() but
neither of these actions retrieve the control. In fact no child controls
exist in the web control, I have implemented INamingContainer and my web
control is dereived from Control.

Any ideas on how I can get reference to my child controls after postback?

Craig
 
R

Riki

Craig said:
Hi

I am developing a web control which creates other web controls.
During the OnInit of the my web control I read an Xml file which
tells my web control which child control to create, adding the child
controls into a private collection.

In the CreateChildControls (override) method, I loop through my
collection of child controls, adding them to the web control:
this.Controls.Add(this.Page.ParseControl(childControlCol));

I do not expose any properties of child controls in the web control.

Everything to this point renders as expected to the page. Say for
example I render a TextBox child control from my collection. The
user enters a value, then does a post back. How can I access the
value of the TextBox control. Normally I would do
this.Controls[childControlId] or a this.FindControl() but neither of
these actions retrieve the control. In fact no child controls exist
in the web control, I have implemented INamingContainer and my web
control is dereived from Control.

Any ideas on how I can get reference to my child controls after
postback?

Craig


Since your subcontrols are created dynamically, you should
recreate them after postback.

The best way to do this is to save enough information
about the state of your control in ViewState, enough
to reconstruct the control after postback (same number
and order of subcontrols).

If you manage to do that, accessing the postback values
will work.

These articles may inspire you:
http://www.dotnetjunkies.com/quicks.../templates/Repeater1.src&file=CS\Repeater1.cs
http://msdn.microsoft.com/library/en-us/dnaspp/html/databoundtemplatedcontrols.asp
 
S

Steve C. Orr [MVP, MCSD]

If you dynamically create controls then you are expected to dynamically
create them again after postback.
If Page.IsPostback though, don't set the value for the control. Let ASP.NET
fill that in for you based on the user's selection.
 
C

Craig

Hi Riki

Thanks for the reply. What is the reason for having a
ViewState["ControlCount"]? I'm not sure if I understand how this will help.
I was not able to reference my postback controls (created dynamically) by
their ID, even though I set this in the Page.ParseControl(...) method. The
only way I was able to retrieve the postback value was though
Request.Forms[...] reference.

Craig

Riki said:
Craig said:
Hi

I am developing a web control which creates other web controls.
During the OnInit of the my web control I read an Xml file which
tells my web control which child control to create, adding the child
controls into a private collection.

In the CreateChildControls (override) method, I loop through my
collection of child controls, adding them to the web control:
this.Controls.Add(this.Page.ParseControl(childControlCol));

I do not expose any properties of child controls in the web control.

Everything to this point renders as expected to the page. Say for
example I render a TextBox child control from my collection. The
user enters a value, then does a post back. How can I access the
value of the TextBox control. Normally I would do
this.Controls[childControlId] or a this.FindControl() but neither of
these actions retrieve the control. In fact no child controls exist
in the web control, I have implemented INamingContainer and my web
control is dereived from Control.

Any ideas on how I can get reference to my child controls after
postback?

Craig


Since your subcontrols are created dynamically, you should
recreate them after postback.

The best way to do this is to save enough information
about the state of your control in ViewState, enough
to reconstruct the control after postback (same number
and order of subcontrols).

If you manage to do that, accessing the postback values
will work.

These articles may inspire you:
http://www.dotnetjunkies.com/quicks.../templates/Repeater1.src&file=CS\Repeater1.cs
http://msdn.microsoft.com/library/en-us/dnaspp/html/databoundtemplatedcontrols.asp
 
I

intrader

Hi Riki

Thanks for the reply. What is the reason for having a
ViewState["ControlCount"]? I'm not sure if I understand how this will help.
I was not able to reference my postback controls (created dynamically) by
their ID, even though I set this in the Page.ParseControl(...) method. The
only way I was able to retrieve the postback value was though
Request.Forms[...] reference.

Craig

Riki said:
Craig said:
Hi

I am developing a web control which creates other web controls.
During the OnInit of the my web control I read an Xml file which
tells my web control which child control to create, adding the child
controls into a private collection.

In the CreateChildControls (override) method, I loop through my
collection of child controls, adding them to the web control:
this.Controls.Add(this.Page.ParseControl(childControlCol));

I do not expose any properties of child controls in the web control.

Everything to this point renders as expected to the page. Say for
example I render a TextBox child control from my collection. The
user enters a value, then does a post back. How can I access the
value of the TextBox control. Normally I would do
this.Controls[childControlId] or a this.FindControl() but neither of
these actions retrieve the control. In fact no child controls exist
in the web control, I have implemented INamingContainer and my web
control is dereived from Control.

Any ideas on how I can get reference to my child controls after
postback?

Craig


Since your subcontrols are created dynamically, you should
recreate them after postback.

The best way to do this is to save enough information
about the state of your control in ViewState, enough
to reconstruct the control after postback (same number
and order of subcontrols).

If you manage to do that, accessing the postback values
will work.

These articles may inspire you:
http://www.dotnetjunkies.com/quicks.../templates/Repeater1.src&file=CS\Repeater1.cs
http://msdn.microsoft.com/library/en-us/dnaspp/html/databoundtemplatedcontrols.asp

From my limited understanding what needs to happen before you can
reference your added controls, is that the controls need to be added to
the DOM. Then the ViewState must be restored for those controls.
Only then can you get at the controls and their data.
 
C

Craig

Hi Steve

This is precisely my issue, how do I re-create the controls on postback
allowing asp.net to assign their values? I haven't implemented any of the
IPostBackHandler... or IPostbackData... interfaces in my web control. Given
my recent posts, can you offer or point me to a sample.

Many thanks, Craig

Steve C. Orr said:
If you dynamically create controls then you are expected to dynamically
create them again after postback.
If Page.IsPostback though, don't set the value for the control. Let ASP.NET
fill that in for you based on the user's selection.




Craig said:
Hi

I am developing a web control which creates other web controls. During
the
OnInit of the my web control I read an Xml file which tells my web control
which child control to create, adding the child controls into a private
collection.

In the CreateChildControls (override) method, I loop through my
collection
of child controls, adding them to the web control:
this.Controls.Add(this.Page.ParseControl(childControlCol));

I do not expose any properties of child controls in the web control.

Everything to this point renders as expected to the page. Say for example
I
render a TextBox child control from my collection. The user enters a
value,
then does a post back. How can I access the value of the TextBox control.
Normally I would do this.Controls[childControlId] or a this.FindControl()
but
neither of these actions retrieve the control. In fact no child controls
exist in the web control, I have implemented INamingContainer and my web
control is dereived from Control.

Any ideas on how I can get reference to my child controls after postback?

Craig

 
C

Craig

Steve

The xml structure goes 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.

Steve C. Orr said:
If you dynamically create controls then you are expected to dynamically
create them again after postback.
If Page.IsPostback though, don't set the value for the control. Let ASP.NET
fill that in for you based on the user's selection.




Craig said:
Hi

I am developing a web control which creates other web controls. During
the
OnInit of the my web control I read an Xml file which tells my web control
which child control to create, adding the child controls into a private
collection.

In the CreateChildControls (override) method, I loop through my
collection
of child controls, adding them to the web control:
this.Controls.Add(this.Page.ParseControl(childControlCol));

I do not expose any properties of child controls in the web control.

Everything to this point renders as expected to the page. Say for example
I
render a TextBox child control from my collection. The user enters a
value,
then does a post back. How can I access the value of the TextBox control.
Normally I would do this.Controls[childControlId] or a this.FindControl()
but
neither of these actions retrieve the control. In fact no child controls
exist in the web control, I have implemented INamingContainer and my web
control is dereived from Control.

Any ideas on how I can get reference to my child controls after postback?

Craig

 
S

Steve C. Orr [MVP, MCSD]

Whatever code you're running to create the controls in the first place, run
it again upon each postback. Call it from the Page_Init or Page_Load event.




Craig said:
Steve

The xml structure goes 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.

Steve C. Orr said:
If you dynamically create controls then you are expected to dynamically
create them again after postback.
If Page.IsPostback though, don't set the value for the control. Let
ASP.NET
fill that in for you based on the user's selection.




Craig said:
Hi

I am developing a web control which creates other web controls. During
the
OnInit of the my web control I read an Xml file which tells my web
control
which child control to create, adding the child controls into a private
collection.

In the CreateChildControls (override) method, I loop through my
collection
of child controls, adding them to the web control:
this.Controls.Add(this.Page.ParseControl(childControlCol));

I do not expose any properties of child controls in the web control.

Everything to this point renders as expected to the page. Say for
example
I
render a TextBox child control from my collection. The user enters a
value,
then does a post back. How can I access the value of the TextBox
control.
Normally I would do this.Controls[childControlId] or a
this.FindControl()
but
neither of these actions retrieve the control. In fact no child
controls
exist in the web control, I have implemented INamingContainer and my
web
control is dereived from Control.

Any ideas on how I can get reference to my child controls after
postback?

Craig

 
L

Ludwig Stuyck

Hi

I am developing a web control which creates other web controls. During the
OnInit of the my web control I read an Xml file which tells my web control
which child control to create, adding the child controls into a private
collection.

In the CreateChildControls (override) method, I loop through my collection
of child controls, adding them to the web control:
this.Controls.Add(this.Page.ParseControl(childControlCol));

I do not expose any properties of child controls in the web control.

Everything to this point renders as expected to the page. Say for example I
render a TextBox child control from my collection. The user enters a value,
then does a post back. How can I access the value of the TextBox control.
Normally I would do this.Controls[childControlId] or a this.FindControl() but
neither of these actions retrieve the control. In fact no child controls
exist in the web control, I have implemented INamingContainer and my web
control is dereived from Control.

Any ideas on how I can get reference to my child controls after postback?

Craig


After postback, CreateChildControls is executed twice. The first time
you need to build the exact web page before the postback, using some
ViewState properties that indicates the previous state of your web
form.

Then you could find your control on the page with FindControl and get
its value, and sets the ViewState properties to the new state.

The second time, you build the new page according to the new
viewstate.

Be sure to implement IPostBackDataHandler, IPostBackEventHandler,
INamingContainer.
 
A

AlanM

Also, be sure to re-create the child controls in the first PostBack
CreateChildControls in the same order and with the same structure as it
was when the control last rendered, so that the ViewState goes into the
correct control. According to "ASP.NET Server Controls and Components"
(p. 311) the base Control class rehydrates viewstate into the controls
using an index, not the ID or type of the child controls.

->AlanM
 

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,482
Members
44,901
Latest member
Noble71S45

Latest Threads

Top