I'm new to ASP.NET.
Im developing ASP.NET C# web form which creating GridView components dynamically and filling them using the data received from my webservice.
I'm creating these GridView components programmatically in server-side (cs file)- it has to be flexible - 1 GridView and sometimes 10 GridView components.
The problem occurs when I'm trying to add pagination - whenever the user clicks the "next" page, the whole page is getting refreshed because of a postBack and I'm loosing all my data and the page returns Blank/Empty.
I used PlaceHolder to hold the GridView components, while searching for a solution, I found UpdatePanel as a better alternative - as far as I understand the page can be partially refreshed - which means that only the UpdatePanel has to be refreshed...but it doesn't work.
The following code sample is my TEST, the UpdatePanel is the only component initiated in the client side (.aspx page), the rest initiated programmatically in .cs .
how can I solve the issue described above?
Why does the whole page is getting refreshed and I'm loosing my data?
can you recommend another way? can provide me with any code sample?
If I'm not rebuilding the GridView, it doesn't work...
Here is my Default.aspx.cs
public partial class TestAjaxForm : System.Web.UI.Page
{
DataTable table;
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
bindGridView();
}
public void bindGridView()
{
GridView gridView1 = new GridView();
gridView1.AutoGenerateColumns = true;
gridView1.PageSize = 2;
gridView1.AllowPaging = true;
gridView1.PagerSettings.Mode = PagerButtons.Numeric;
gridView1.PagerSettings.Position = PagerPosition.Bottom;
gridView1.PagerSettings.PageButtonCount = 10;
gridView1.PageIndexChanging += new GridViewPageEventHandler(this.GridView1_PageIndexChanging);
table = new DataTable();
table.Columns.Add("FirstName");
table.Columns.Add("LastName");
DataRow row = table.NewRow();
row["FirstName"] = "John";
row["LastName"] = "Johnoson";
table.Rows.Add(row);
row = table.NewRow();
row["FirstName"] = "Johnny";
row["LastName"] = "Marley";
table.Rows.Add(row);
row = table.NewRow();
row["FirstName"] = "Kate";
row["LastName"] = "Li";
table.Rows.Add(row);
panel.ContentTemplateContainer.Controls.Add(gridView1);
gridView1.DataSource = table;
gridView1.DataBind();
}
protected void GridView1_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
GridView gridView1 = (GridView)sender;
gridView1.PageIndex = e.NewPageIndex;
gridView1.DataSource = table;
gridView1.DataBind();
}
}
Thank you.
If you want a custom GridView approach to work, you have to recreate and rebind the grid on every page load... that's the problem with dynamic Grids... Dynamic controls don't retain their viewstate, but if you added the grid and dynamically generated the columns, that would work easier for you (because I think it may dynamically remember the columns, or you can set AutoGenerateColumns to true, and it brings in your data row column names).
HTH
You should create your GridView and add it to the control tree in the PreInit or Init event handler so that they have a chance to properly bind to ViewState, and it should be done whether or not there's a postback: if you don't add them in a postback, they obviously won't be there to display anything.
DataBinding can happen later in the page life cycle.
Paging only seems to work if you also use an ObjectDataSource; I've never been able to get it to work with a GridView by itself.
I think the easiest thing to do is have the gridview declared in the aspx page inside the place holder, while the place holder is also contained inside the update panel.
For what I can see, John is not doing anything that can't be declared in the markup itself so that shouldn't be a problem. If for some reason the gridview should not be displayed on the screen, it suffices to set the Visible property of the placeholder to false.
As far as paging is concerned, as RickNz correctly points out, it will only retain the state if you bind the gridview to either a LinqDatasource, SqlDatasource or ObjectDatasource but if you bind it to custom business objects, what you need to do is save the data in Session and rebind it again on PageIndexChanged.
In pseudo code, would be sometging like this.
Page_load
{
If (!IsPostBack)
Binddata();
}
private void Binddata()
{
var data = Getdata();
Gridview1.DataSource= data;
Gridview.DataBind();
Session["data"]=data; // cache the data
}
protected void Gridview1_indexchanged(object sender, GridviewPageEventArgs e)
{
var data= Session["data"];
Gridview1. DataSource=data;
Gridview1.DataBind();
GridView1.PageIndex=e.NewPageIndex;
}
Related
I want to update row in GridView with this code but after editing GridView not changes:
protected void res_RowUpdating(object sender, GridViewUpdateEventArgs e)
{
//Retrieve the table from the session object.
DataTable dt = (DataTable)Session["dt"];
GridViewRow row =res.Rows[e.RowIndex];
dt.Rows[row.DataItemIndex]["name"] = ((TextBox)(row.Cells[6].Controls[0])).Text;
dt.Rows[row.DataItemIndex]["dewey"] = ((TextBox)(row.Cells[5].Controls[0])).Text;
*dt.Rows[row.DataItemIndex]["subject"] = ((TextBox)(row.Cells[4].Controls[0])).Text;
Session["dt"] = dt;
res.EditIndex = -1;
res.DataSource = dt;
res.DataBind();
}
my Page_Load:
protected void Page_Load(object sender, EventArgs e)
{
DataTable dt;
if (!IsPostBack)
{
dt= Converter.ListBooks(new classes.Book().GetAll());
Session["dt"] = dt;
res.DataSource = dt;
res.DataBind();
}
else
{
dt=(DataTable)Session["dt"];
res.DataSource = dt;
res.DataBind();
}
}
for example I changed line that have * to this:
dt.Rows[row.DataItemIndex]["subject"] = "tx";
and after edit "subject" column changed to "tx", so I don't know why ((TextBox)(row.Cells[4].Controls[0])).Text return TextBox's text before edit?
Because you're calling DataBind(); method each time page refreshed (POST or GET), let me explain more if user put the new value in the TextBox and click on update button to trigger res_RowUpdating even Page_Load will fire and bind the Gird with database values which is the old values and neglect the user input value.
I think, you just need to rebind the grid
Remove the else part in your page_load.
Should do it for you.
You are binding the Grid every time there is a postback which is not required.
Maybe changes are done but the form is not being updated.
Try putting gridview control inside an Update Panel Control and call UpdatePanel.Update().
When you work with a web control, what you see can be different from what actually is because changes in data are not autoupdated in the presentation layer.
To solve this "problem" you can make a postback (retrieving everything) of the whole page, but this is like killing a fly with a bazooka because you do not need everything, just what has been updated, so for this purpose there are several tool that allow you to make partial updates, for example the AJAX control: UpdatePanel.
Hope it helps.
Update: Call the AcceptChanges() method on the DataTable and erase the else branch on the Page_Load after if(!PostBack)
Call the AcceptChanges() method of the DataTable and then bind the GridView.
I have an ASP.Net gridview which is binding properly.On edit i am editing certain fields.then after i need to edit other rows as well.But when i am trying to edit other rows the previously edited rows get reset n retain their older values.
The requirement is as such that i have to edit many rows and the on a button click i need to push all the edit values to the database
You need to maintain your GridView's datasource between postbacks.
You can do this by storing your DataTable in Cache, Session, or any persistent storage.
Upon edit of a row, save the changes to this DataTable, then rebind the Gridview (from this DataTable).
When the user clicks "save all", you can save the changed rows of the DataTable to the database.
If you need to keep track of which rows have changed, you can maintain a list of PrimaryKeys that have changed in cache or Session.
Are you checking !IsPostBack inside Page_Load event before binding the grid? If you are not binding the grid in Page_Load event, please post the code to bind the grid.
The problem with your code is,you r binding grid on page load.. so when page is loading , it can bind the values which are in database. for that write bind method on Post back and also maintain your values on sessions or Hidden Fields,when you click on save button update database with that sessions or hidden fields..
morning bryan...here is that code for getting the value from the gridview to the datatable
private void getGridInfo()
{
DataTable dt = new DataTable();
DataRow dr;
dt.Columns.Add(new System.Data.DataColumn("Select", typeof(byte)));
dt.Columns.Add(new System.Data.DataColumn("Client", typeof(string)));
dt.Columns.Add(new System.Data.DataColumn("PrincipleAmt", typeof(double)));
foreach (GridViewRow row in grdRepayment.Rows)
{
CheckBox Select = (CheckBox)row.FindControl("ChkSelect");
Label ClientName = (Label)row.FindControl("lblClientName");
Label Principal = (Label)row.FindControl("lblPricipal");
dr = dt.NewRow();
dr[0] = Convert.ToByte(Select.Checked);
dr[1] = ClientName.Text;
dr[2] = Convert.ToDouble(Principal.Text);
dt.Rows.Add(dr);
}
Session["TempTable"] = dt;
}
now here is the code for updating that session variable which holds the datatable,this must be done in RowUpdating Event of the Gridview.
protected void grdRepayment_RowUpdating(object sender, GridViewUpdateEventArgs e)
{
DataTable myDatatable;
GridViewRow row = grdRepayment.Rows[e.RowIndex];
grdRepayment.EditIndex = -1;
if (row != null)
{
myDatatable = (DataTable)Session["TempTable"];
for (int i = 0; i < myDatatable.Rows.Count; i++)
{
if (e.RowIndex == i)
{
myDatatable.Rows[i][1] = Convert.ToString(Client);
myDatatable.Rows[i][2] = Convert.ToString(Principal);
Session["TempTable"] = myDatatable;
grdRepayment.EditIndex = -1;
grdRepayment.DataSource = myDatatable;
grdRepayment.DataBind();
}
}
}
}
and make sure you bind the grid from this session variable only in RowEditing and RowCancellingEdit Events.
Once you are done with the Editing thing simply click the button which will push the edited content to the DATABASE...
Please check you'r gridview binding method was call page load and inside of !isPostBack?
for
Void page_load()
{
if(!IsPostBack)
{
//Call GridView Binding method
}
}
protected void grdRepayment_RowEditing(object sender, GridViewEditEventArgs e)
{
grdRepayment.EditIndex = e.NewEditIndex;
myDatatable = (DataTable)Session["TempTable"];
grdRepayment.DataSource = myDatatable;
grdRepayment.DataBind();
}
This is how we need to Bind the grid in RowEditing and RowCancelingEdit
I have a gridview, and I have a SelectedIndexChanged event on it...
protected void GridView1_SelectedIndexChanged(object sender, EventArgs e)
{
GridViewRow Row = GridView1.SelectedRow;
//do some stuff
}
Then I get an error...
Index was out of range. Must be non-negative and less than the size of the collection.
Parameter name: index
I do not understand why, the Gridview is being binded in pageload. but not in post back...
if (!IsPostBack)
{
GridView1.DataSource = UserAccounts;
GridView1.DataBind();
}
The asp.net DataSource controls handle this for you automatically but if you are manually binding your GridView, you will need to also bind it on PostBack. If you make changes to the data source based on filters, etc., you will need to rebind it.
The first thing: When post back to server, your GridView1 will re-initialize so that GridView1.DataSource will lost the previous data
if (!IsPostBack)
{
GridView1.DataSource = UserAccounts;
GridView1.DataBind();
}
The second thing: if you manually bind your GridView with your custom DataTable, List .... you must implement RowCommand with specific DataKey.
Please take a look at this article http://aspspirits.blogspot.com/2012/08/how-to-get-rowindex-of-aspnet-gridview.html
when i click Add button i need to create gridview dynamically, where the gridview has to contain Textbox,DatePicker and dropdownlist.where as the values entered in each row of the gridview have to store it in database and retrive.
To get you started, an object is generally created dynamically in C# like this:
DataGridView g = new DataGridView();
The rest of the stuff you're asking - the textbox, datepicker, dropdownlist columns and reading/writing to the database - is quite involved and can't be answered here in any simple way.
You can just Bind the GridView onClick of Add Button
Like this
protected void btnADD_Click(object sender, EventArgs e)
{
objENT = new ENT();//using n-tier Architecture
objENT.ProcType = "ProcedureType";
DataSet ds = BLL.ProcessGrid(objENT);
GridviewDisplay.DataSource = ds;
GridviewDisplay.DataBind();//GridviewBind
}
I have used stored Procedure here,You can use any other methods as u wish
I have an ASP.NET web app (C#) where I get some information from a datasource and display it in the the gridview. I wanted to enable paging, but for some reason, paging doesn't work. I researched a little online, and I found that paging is done differently if a dataset is used. When I click on a page number, it refreshes, and says that there are no records to display. I call this function in the click function of a button:
bindGrid(cmd);
Here's my bind method:
private void bindGrid(OracleCommand comm)
{
OracleDataAdapter adapter = new OracleDataAdapter(comm);
DataSet ds = new DataSet();
ds.Tables.Add("Results");
adapter.Fill(ds.Tables["Results"]);
grd.DataSource = ds;
grd.DataBind();
}
Paging Method:
protected void grdResults_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
grd.PageIndex = e.NewPageIndex;
grd.DataBind();
}
How am I supposed to do paging with a dataset? Can someone help please?
You also need to fetch the data :)
So instead of this:
protected void grdResults_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
grd.PageIndex = e.NewPageIndex;
grd.DataBind();
}
you should use:
protected void grdResults_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
grd.PageIndex = e.NewPageIndex;
//Create command
bindGrid(comm);
}
Instead of grd.DataBind() in your paging method call bindGrid(). Or better use some built-in 'business objects' for data binding like ObjectDataSource
The simplest way to do paging is to set AllowPaging="yes" in your GridView, and don't do anything in the code-behind. The GridView will page through its dataset on its own. Do NOT rebind.
That's fine for small datasets, but not so good for a phone book. As Tadas said, ObjectDataSource is the way to go for handling paging yourself, on server side. With ObjectDataSource, you won't DataBind at all; the controls handle that. However, you do need to supply a Select method (usually static) on an object, and it needs to have parameters for first row and page size (set these as attributes on the ObjectDataSource). You will allso need to implement a Count method to return the full dataset size; otherwise paging won't work. Using an ObjectDataSource this way, you shift the burding of paging to your data layer, and the page will load much faster.