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.
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:
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:
Row 1
Child Grid 1
Column 1 Column 2 Column 3 Column 4 Column 5
Label Checkbox Checkbox CheckBox Checkbox
Row 2
Child Grid 2
Column 1 Column 2 Column 3
Label Checkbox TEXTbox
Row 3
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.
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.
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.
Superguppie.
Please remember to click “Mark as Answer” on the post that helps you. This can be beneficial to other community members reading the thread.
When all you've got is a Hammer, Every Problem looks like a Nail. Michael Swain.
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.
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.
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;
gridView1.DataBind();
}
}
"Don't sweat the petty things, and don't pet the sweaty things"
- George Carlin
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.
Superguppie.
Please remember to click “Mark as Answer” on the post that helps you. This can be beneficial to other community members reading the thread.
When all you've got is a Hammer, Every Problem looks like a Nail. Michael Swain.
WPUBrett
Member
10 Points
8 Posts
Losing Dynamic Controls In a Gridview on Postback
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.
Any ideas?
Thanks
</div>Ana D.
Member
139 Points
86 Posts
Re: Losing Dynamic Controls In a Gridview on Postback
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.
barryman9000
Participant
1698 Points
605 Posts
Re: Losing Dynamic Controls In a Gridview on Postback
May 22, 2012 10:59 PM|LINK
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:
if(!Page.IsPostBack) { //Create Child Gridview controls }- George Carlin
WPUBrett
Member
10 Points
8 Posts
Re: Losing Dynamic Controls In a Gridview on Postback
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:
Row 1
Child Grid 1
Column 1 Column 2 Column 3 Column 4 Column 5
Label Checkbox Checkbox CheckBox Checkbox
Row 2
Child Grid 2
Column 1 Column 2 Column 3
Label Checkbox TEXTbox
Row 3
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.
Qin Dian Tan...
All-Star
113532 Points
12480 Posts
Microsoft
Re: Losing Dynamic Controls In a Gridview on Postback
May 24, 2012 08:13 AM|LINK
Hi,
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.
Thanks,
If you have any feedback about my replies, please contactmsdnmg@microsoft.com.
Microsoft One Code Framework
superguppie
All-Star
48225 Points
8679 Posts
Re: Losing Dynamic Controls In a Gridview on Postback
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.
Please remember to click “Mark as Answer” on the post that helps you. This can be beneficial to other community members reading the thread.
When all you've got is a Hammer, Every Problem looks like a Nail. Michael Swain.
WPUBrett
Member
10 Points
8 Posts
Re: Losing Dynamic Controls In a Gridview on Postback
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.
WPUBrett
Member
10 Points
8 Posts
Re: Losing Dynamic Controls In a Gridview on Postback
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.
barryman9000
Participant
1698 Points
605 Posts
Re: Losing Dynamic Controls In a Gridview on Postback
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; gridView1.DataBind(); } }- George Carlin
superguppie
All-Star
48225 Points
8679 Posts
Re: Losing Dynamic Controls In a Gridview on Postback
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.
Please remember to click “Mark as Answer” on the post that helps you. This can be beneficial to other community members reading the thread.
When all you've got is a Hammer, Every Problem looks like a Nail. Michael Swain.