How do I find a grid control ona web page in a post back?

  • Thread starter Thread starter Jim H
  • Start date Start date
J

Jim H

We ahve a .NET web page that we dynamically create a bunch of DataGrids and
add them to a place holder. When the user hits submit we need to go through
all of the DataGrids to get some data. We can't seem to find the grids on
the post back, the PlaceHolder.Controls.Count is 0. How do we get that data
back.

The DataGrids have check boxes that the user may have checked. Those are
the rows we want to get so we can't just requery and rebind.

Any ideas?

Thanks,
Jim
 
Hi Jim,

Thanks for posting in this group.
Based on my understanding, you wanted to dynamic create some datagrids and
add to the placeholder, but when you postback, you find the placeholder's
child control collection is empty.
I did not see you code, but I think when postback you may forget to
recreate the datagrids and rebind to these controls.
If you do like this, it should work. Code snippet listed below:

private void Page_Load(object sender, System.EventArgs e)
{
// Put user code to initialize the page here
dg1=new DataGrid();
DataGrid dg2=new DataGrid();
DataGrid dg3=new DataGrid();
SqlDataAdapter adapter=new SqlDataAdapter("select * from
jobs","server=localhost;database=pubs;uid=sa;pwd=");
DataSet ds=new DataSet();
adapter.Fill(ds);
dg1.DataSource=ds;
dg1.DataBind();
dg2.DataSource=ds;
dg2.DataBind();
dg3.DataSource=ds;
dg3.DataBind();
PlaceHolder1.Controls.Add(dg1);
PlaceHolder1.Controls.Add(dg2);
PlaceHolder1.Controls.Add(dg3);
}

Private void Button1_Click(object sender, System.EventArgs e)
{
Response.Write(PlaceHolder1.Controls.Count.ToString());
}

Best regards,
Jeffrey Tan
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.
 
I understand that, but the problem is I can't get the data from the database
again for 2 reasons. 1 It may have changed, and 2 I'm trying to get the
items the user selected form the datagrids. If I reload them I don't know
which items they selected. Especially if a new record comed back in the
middle of the old ones.

These datagrids have a checkbox column. I need to go through the grids and
find which rows were checked.
Thanks,
jim
 
Hi Jim,

Thanks for your feedback.
For your first reason, I think you should store your dataset in session
variable or viewstate, when postback, you can bind your datagrid with the
old dataset.
For your second reason, how do you implement your "row selection" in
webform datagrid? If you implement it through checkbox column(I think this
column is also customized by you), I think you can expose a property in
your customized checkbox column which returns its checkbox's checked state.
The article below customize a checkbox column expose the checkbox checked
state:
http://www.codeproject.com/aspnet/datagridcheckboxcol.asp

Use these 2 ways, I think you can get what you want, if there is still
anything unclear, please feel free to tell me.

Best regards,
Jeffrey Tan
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.
 
Thanks for the response Jeffrey,
We do use a custom check box column that I got form this news group and it
returns an array of indexes of items that were checked.

We can not use a session variable because the users connect to a web server
via a virtual IP. There is some middle where that distributes the requests
between 3 or 4 web servers. We may not end up on the same web server
between connections and postbacks. I believe viewstate is what I want to
use but haven't been able to figure out how to use it. We set ViewState to
true which is supposed to be the default) on each datagrid but we can never
find the datagrids. When a control is dragged onto the form and given an ID
we can just refer to it by name. There must be something else that enables
the control to be able to be referencable on a postback. I just don't know
what.

Any ideas?

Thanks again,
jim
 
Hi Jim,

Thanks for your feedback.
To store dataset in ViewState, you should first convert the dataset into
string. To fulfill this, you can use stringreader and stringwriter.

Sample code snippet like this:

protected DataSet ds;
private void Page_Load(object sender, System.EventArgs e)
{
// Put user code to initialize the page here
DataGrid dg1=new DataGrid();
DataGrid dg2=new DataGrid();
DataGrid dg3=new DataGrid();

ds=new DataSet();
if(!IsPostBack)
{
SqlDataAdapter adapter=new SqlDataAdapter("select * from
jobs","server=localhost;database=pubs;uid=sa;pwd=");
adapter.Fill(ds);
StringWriter sw=new StringWriter();
ds.WriteXml(sw);
ViewState["ds"]=sw.ToString();
}
else
{
StringReader sr=new StringReader((string)(ViewState["ds"]));
ds.ReadXml(sr);
}
dg1.DataSource=ds;
dg1.DataBind();
dg1.EnableViewState=true;
dg2.DataSource=ds;
dg2.DataBind();
dg3.DataSource=ds;
dg3.DataBind();

PlaceHolder1.Controls.Add(dg1);
PlaceHolder1.Controls.Add(dg2);
PlaceHolder1.Controls.Add(dg3);


DataGrid1.DataSource=ds;
DataGrid1.DataBind();
}

It works well on my machine, if you still have anything unclear, please
feel free to tell me.

Best regards,
Jeffrey Tan
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.
 
Thanks, I think I see how that solves my problem. Will the datagrids that
get rebound still have the same rows checked in the check box columns? To
put it even simpler, if the user clicked on a row in the grid, would the
SelectedItem property still be set to the correct row?

Just out of curiosity, is there a way to gain access to the grid control
objects that I added dynamically like I would a grid control that I dropped
on the form from the toolbox?

Thanks again,
Jim
 
Hi Jim,

Thanks for your feedback.
For your further question, I will do some research, I will reply to you
ASAP.
Thanks for your understanding.

Best regards,
Jeffrey Tan
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.
 
Hi Jim,

After my research, I find that the datagrid control will do the viewstate
management for its content.
So you even need not save the dataset to viewstate yourself.
The code below proved this:
private void Page_Load(object sender, System.EventArgs e)
{

DataGrid dg1=new DataGrid();
dg1.EnableViewState = false;
DataGrid dg2=new DataGrid();
DataGrid dg3=new DataGrid();

SqlDataAdapter adapter=new SqlDataAdapter("select * from
jobs","server=localhost;database=pubs;uid=sa;pwd=");
DataSet ds=new DataSet();
adapter.Fill(ds);

this.Controls.Add(dg1);
this.Controls.Add(dg2);
this.Controls.Add(dg3);

if(!IsPostBack)
{
dg1.DataSource=ds;
dg1.DataBind();
dg1.EnableViewState=true;
dg2.DataSource=ds;
dg2.DataBind();
dg3.DataSource=ds;
dg3.DataBind();

DataGrid1.DataSource=ds;
DataGrid1.DataBind();
}
}

You should place a button on the web form, when click, the form will post
back to server side, because dg1.EnableViewState = false, the datagrid1
will disappear.
While the other datagrids will remain with the origianl data, althrough
they did not rebind to database.

For your checkbox row selection problem, I think I meet some problem. When
I dynamicly add the TemplateColumn to the datagrid, if my datagrid did not
rebind to datasource, this column will disappear, code like this:

private void Page_Load(object sender, System.EventArgs e)
{
// Put user code to initialize the page here
TemplateColumn tc=new TemplateColumn();
tc.ItemTemplate=new checkboxtemplate();
DataGrid1.Columns.Add(tc);

if(!IsPostBack)
{
SqlDataAdapter adapter=new SqlDataAdapter("select * from
jobs","server=localhost;database=pubs;uid=sa;pwd=");
DataSet ds=new DataSet();
adapter.Fill(ds);

DataGrid1.DataSource=ds;
DataGrid1.DataBind();
}
}

public class checkboxtemplate: ITemplate
{
public void InstantiateIn(Control container)
{
CheckBox cb=new CheckBox();
container.Controls.Add(cb);
}
}

When click a button to postback, my TemplateColumn disappeared.

I will spend more time to figure it out. Thanks for your understanding.

Best regards,
Jeffrey Tan
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.
 
Hi Jim,

Thanks for your feedback.
Oh, I have found out the trick.
Actually, the web server control will automatically persists its state in
viewstate, but the dynamic added controls(or columns) are not automatically
added to the page's view state, so you are obliged to add logic to the page
to make sure the persistant with each round trip.
An good way to do is to override page's LoadViewState method:

using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Data.SqlClient;
using System.Drawing;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;

namespace checkboxvaluedatagrid
{
public class WebForm1 : System.Web.UI.Page
{
protected System.Web.UI.WebControls.Button Button1;
private DataGrid dg1=null ,dg2=null;
protected System.Web.UI.HtmlControls.HtmlForm Form1;

private void Page_Load(object sender, System.EventArgs e)
{
if(!IsPostBack)
{
addcolumn();

SqlDataAdapter adapter=new SqlDataAdapter("select * from
jobs","server=localhost;database=pubs;uid=sa;pwd=");
DataSet ds=new DataSet();
adapter.Fill(ds);

dg1.DataSource=ds;
dg1.DataBind();
dg2.DataSource=ds;
dg2.DataBind();
}
}

protected override void LoadViewState(object savedState)
{
base.LoadViewState (savedState);
addcolumn();
}

public void addcolumn()
{
dg1=new DataGrid();
dg2=new DataGrid();

TemplateColumn tc=new TemplateColumn();
tc.ItemTemplate=new checkboxtemplate();

dg1.Columns.Add(tc);
dg2.Columns.Add(tc);

Form1.Controls.Add(dg1);
Form1.Controls.Add(dg2);
}

public class checkboxtemplate: ITemplate
{
public void InstantiateIn(Control container)
{
CheckBox cb=new CheckBox();
cb.ID="checkbox";
container.Controls.Add(cb);
}
}

#region Web Form Designer generated code
override protected void OnInit(EventArgs e)
{
InitializeComponent();
base.OnInit(e);
}

private void InitializeComponent()
{
this.Button1.Click += new System.EventHandler(this.Button1_Click);
this.Load += new System.EventHandler(this.Page_Load);

}
#endregion

private void Button1_Click(object sender, System.EventArgs e)
{
foreach(DataGridItem item in dg1.Items)
{
CheckBox myCheckbox = (CheckBox)item.Cells[0].Controls[0];
if(myCheckbox.Checked == true)
{
Response.Write(item.ItemIndex.ToString());
}
}
}
}
}

Note: I dynamic add 2 datagrid into the "FORM" control collection(Can not
be the page's control collection, because the checkbox column will interact
with server side)
In Button1_Click, I only retrieve the first datagrid's checkbox column
state.
It works well on my machine, if you have anything unclear, please feel free
to tell me.

Merry Christmas!!

Best regards,
Jeffrey Tan
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.
 
Hi Jim,

Did my reply resolve your problem?
If you still have any concern, please feel free to tell me. I am glad to
work with you.

Best regards,
Jeffrey Tan
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.
 
Thanks Jeffrey. Sorry I didn't say thanks earlier. We haven't tried it
yet. We had to change the design and work around the issue because of a
time constraint. We may put the multiple datagrid version code back in at a
later time. The code you sent me looks like it will do the trick and it
gave us some insight into how things work.

Thanks again for all your help!

Jim
 
Back
Top