Data-driven Templated Controls (GridView)

M

Mark Olbert

I'm running into a well-described issue in the ASPNET model that I haven't found a good work around for.

I have a GridView to which I dynamically add data-bound TemplateFields at run-time. The specific fields that are added depend on the
state of the application.

The contents of these fields displays properly after they are first initialized, but not after postback (e.g., just a simple button
control that doesn't do anything except trigger the postback). This is the well-described issue -- it's apparently due to the fact
that they dynamically added controls must be recreated in the page life cycle before the point where viewstate is loaded.

My problem is that the specific controls that are added depend on the >>state<< of the application...which is itself stored in
viewstate (well, actually controlstate, but for this discussion I don't think that should matter).

So I think I have a chicken-and-egg situation: I have to recreate the dynamically-added TemplateFields >>before<< viewstate is
loaded, but I don't know which TemplateFields to add until >>after<< viewstate is loaded.

I hope that's a reasonably clear description of the problem/issue. Is there an approach that lets me resolve this conundrum? Is
there a way to load or examine viewstate/controlstate "early"?

- Mark
 
W

Walter Wang [MSFT]

Hi Mark,

Dynamically added controls don't have to be recreated before the point
where viewstate is loaded. For example, you could dynamically create some
control during Page_Load and they will still get state restored correctly.
The reason it may work is because the Controls.Add() method recursively
loads the parent's view state into its children, even though the load view
state stage has passed. (See
http://msdn2.microsoft.com/en-us/library/ms972976.aspx, section "View State
and Dynamically Added Controls")


I'm not sure about your exact requirement regarding dynamically added
TemplateField for GridView, therefore I cannot guarantee this will also
work in your case. I can depict more if you could some of your code.


Regards,
Walter Wang ([email protected], remove 'online.')
Microsoft Online Community Support

==================================================
When responding to posts, please "Reply to Group" via your newsreader so
that others may learn and benefit from your issue.
==================================================

This posting is provided "AS IS" with no warranties, and confers no rights.
 
M

Mark Olbert

Walter,

Thanx for the link to the article. I'll play around with the problem some more and post the results here.

Something that I didn't mention earlier is that not all of the dynamically-added controls demonstrate this problem. Here's what I'm
doing in pseudo-code when I first update the GridView dynamically:

Add CommandField control to GridView
Add TemplateField control to GridView
Add TemplateField control to GridView
Add BoundField control to GridView
....
DataBind() GridView
....
Render Page

On postback, if I do nothing (i.e., don't add the dynamically-added field controls again), the CommandField and BoundField controls
display their values. It's the TemplateFields that don't show up.

Adding all the field controls on postback as early as I can gives the same result: the BoundField and CommandField show up, the
TemplateFields do not. I haven't tried databinding on postback, but I suspect that will cause the TemplateFields to display
properly.

So the issue seems to involve TemplateFields not retaining the results of having been bound to data. Is there something I need to do
to get them to retain the info? Or do TemplateFields just require being re-bound on each postback?

- Mark
 
M

Mark Olbert

Walter,

Some more information, and -- I hope! -- a solution.

In all my previous experimentation I was focusing on recreating the >>columns<< in the GridView on postback. Unfortunately, changing
the columns on postback doesn't do a thing to the child controls embedded in the GridView.

The solution I think I've found is to recreate the >>controls<< in the GridView cells instead. When you do that, they load their
viewstate and display properly. As an aside, I also specifically assigned IDs to the controls created in the TemplateFields because
I've run into problems in other areas when you just leave it up to .NET to assign IDs to dynamically-created controls.

In pseudo-code what I do is this:

On initial dynamic configuration of the GridView:

foreach column to be added
if the column is templated
Create TemplateField
Add instance of custom ITemplate object to TemplateField's ItemTemplate.

The custom ITemplate object's InstantiateIn() method creates a Label to hold information and assigns it a unique ID (I use Labels
because I just need to display data). The unique ID just needs to be unique within a row, since the GridViewRow is the
NamingContainer. I use something like "lbl<name of data field that the column is displaying>".

On postback:

foreach column in the GridView
if column is TemplateField
foreach row in GridView
create an instance of Label (with the same unique ID as used in initial configuration)
add instance of Label to controls for the column's cell in the row

This restoration needs to take place after the InitComplete event (I do it in the Load event handler) because before then the rows
have not been restored to the GridView.

- Mark
 
W

Walter Wang [MSFT]

Hi Mark,

Thanks for sharing your solution with the community.

Yes it's recommended to assign an unique ID to each dynamically created
control to make sure correct state is restored correctly; otherwise the
order of the controls that are added to the container will be used to
restore the state.


Regards,
Walter Wang ([email protected], remove 'online.')
Microsoft Online Community Support

==================================================
When responding to posts, please "Reply to Group" via your newsreader so
that others may learn and benefit from your issue.
==================================================

This posting is provided "AS IS" with no warranties, and confers no rights.
 

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,994
Messages
2,570,223
Members
46,812
Latest member
GracielaWa

Latest Threads

Top