Get Help:Ask a Question in our Forums|Report a Bug|More Help Resources
Last post May 25, 2012 04:02 PM by WPUBrett
May 22, 2012 05:59 PM|LINK
I saw a few older threads on this, but no real answers.
I am building a nested Gridview. I have to add a child Gridview to each row of the parent dynamically. Both the layout and content of the child Gridviews
are based on the data from the parent row. For example, one child Gridview may have 5 columns, another 6, another 4, and some no child gridview at all. It all depends on the parent row's data.
I am dynamically creating the child Gridviews in the RowDataBound event of each parent row, adding controls to TemplateFields. I also looked at the RowCreated event, but not knowing the data yet stopped me. The page loads great the first time, but when
I do a PostBack, the child Gridviews still have the correct row and column counts, but no data/controls. I'm assuming the ViewState remembers the data since, the row and column counts are correct, but perhaps the dynamic controls in TemplateFields are lost.
May 22, 2012 10:52 PM|LINK
Are you rebinding the gridview after the post back?
Try posting your code here, so we can try looking what is wrong.
May 22, 2012 10:59 PM|LINK
I'm assuming the ViewState remembers the data since, the row and column counts are correct, but perhaps the dynamic controls in TemplateFields are lost.
Whenever you create a dynamic control, you have to recreate it on each post back. Is the code that creates those controls(within the child gridviews) in something like this:
//Create Child Gridview controls
May 23, 2012 11:57 AM|LINK
Yeah, I had heard I have to recreate the dynamic controls on each postback. Kicker is that each child grid's layout depends on the data bound to its parent row. For example:
Child Grid 1
Column 1 Column 2 Column 3 Column 4 Column 5
Label Checkbox Checkbox CheckBox Checkbox
Child Grid 2
Column 1 Column 2 Column 3
Label Checkbox TEXTbox
Child Grid 3
Column 1 Column 2 Column 3 Column 4
Label Checkbox TEXTbox Checkbox
NOTE: the layout of Child Grid 1 (column count, controls in cells) depends on the data bound to Row 1, Grid 2 depends on Row 2 , etc.. Again talking design, not grid data content. Each postback must also remember any data entry, such as Checkboxes checked
off or Textbox entries in each child grid.
Was hoping there might be an efficient way to do this.
May 24, 2012 08:13 AM|LINK
It is hard to maintain the state of dynamic GridView, especially the nested one. For losing controls in nested GridView, you can remove the postback checking around the binding code of parent GridView. This means the nested GridView will be created in every
postback event. For maintaining the values in controls, I have no idea.
May 24, 2012 03:05 PM|LINK
GridView keeps the data it needs to rebuild its structure in ViewState. That's how it rebuilds on PostBack. However, there is quite a bit it doesn't keep there. Your GridViews with custom layout seem to have parts that are not in ViewState, as they are not
restored. You will have to do the "store in ViewState and rebuild" yourself.
Store information on what you are doing in ViewState in the RowDataBound handler. In the RowCreated handler see if there is ViewState. If there is, use it to recreate. If not, the GridView is DataBinding. So no need to do anything.
If the Controls are properly recreated on PostBack, they in turn will use ViewState to restore their content.
May 24, 2012 03:56 PM|LINK
Well I took two steps forward and one step back.
I rebind the nested grids on every postback, and as long as I assure each dynamic control has a unique ID, the ViewState repopulates them and any events, like CheckedChanged fire. However, now my parent row controls (declared in the ASPX) do not recover
from the ViewState nor do any of their events fire. I guessing the rebind corrected my dynamic control problem, but clobbered my ASPC controls.
May 24, 2012 04:03 PM|LINK
Let me clarify, couldn't think of the correct term. The dynamic controls now work with ViewSate and event firing, but the static ones DON'T work with either. I kill the postback databind, as a test, and the situation flip-flops.
May 24, 2012 05:31 PM|LINK
I've had a similar situation. You'll have to update your datasource (like a DataTable object) on each post back with the altered values on your web page (ie if someone entered text in a textBox or checked a CheckBox) then bind that updated datasource to
your gridView. The easiest way to do this is to store the unique ID for each row in a hidden field in your gridview. Something like this (code is untested!):
// If the user can enter a different Quantity in a textbox for example
// update the datasource (DataTable dt in this case) then bind
protected override void OnLoad(EventArgs e)
//Fill your DataTable with your DB items
DataTable dt = YourClass.GetAllItems();
//If the gridview doesn't have any items, then this is the first PageLoad so just skip to the dataBind()
if(gridView1.Items.Count != 0)
foreach (GridViewRow gridViewRow in gridView.Rows)
//find the hidden control and get the row/item's unique ID
int iGridViewItemId = Convert.ToInt16(((HiddenField)gridViewRow.FindControl("hiddenItemId")).Value);
//Compare the ID from your DataSoure with the with the ID in the hidden field
foreach (DataRow dataRow in dtTemp.Rows)
int iDataItemId = Convert.ToInt16(dataRow["ID"].ToString());
//If they match, then get whatever is in the TextBox
if (iDataItemId == iGridViewItemId)
// update the Datatable with the value from the textbox
dataRow["QUANTITY"] = Convert.ToInt16(((TextBox)gridViewRow.FindControl("tbQuantity")).Text);
// Now your dataSource (dt) is updated with the Quantity values from the tbQuantity textbox. So if
// the user changed any of those values, they will be reflected in the DataTable
gridView1.DataSource = dt;
May 25, 2012 01:08 PM|LINK
Where do you do the rebuilding/databinding? Page_Load and the Load events are too late.
My suggestions earlier are intended to fit in with the ASP.NET Page Life Cycle. This is to avoid DataBind on PostBack. Just restoring Controls from ViewState should be enough to make them use their respective ViewStates to rebuild.