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.
Related
How do I add paging to this GridView?
C# code:
protected void GridView1_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
GridView1.PageIndex = e.NewPageIndex;
GridView1.DataBind();
}
Error
Specified argument was out of the range of valid values. Parameter name: index
You again you need to in page index changing event. Here you have not written that.
See the link
myGridView.DataSource = your datasource here;
myGridView.PageIndex = e.NewPageIndex;
myGridView.DataBind();
I think what I do is I write the page index code and then call the actrual bindmethod of the grid after that:
myGridView.PageIndex = e.NewPageIndex;
BindmyGridView();
where
private void BindmyGridView()
{
myGridView.DataSource = lst; //where lst is the datasource
myGridView.DataBind();
}
Also have you gone through these links:
Link 1
Link 2
Allow paging is very simple.Call PageIndexChanging event of grid view like
protected void GridView1_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
GridView1.PageIndex = e.NewPageIndex;
GridView1.DataSource = Your datasource here;
GridView1.DataBind();
}
Hope it works for you..
You need to use a pageable data source. The simplest way is to just use an SqlDataSource.
Also, note that PageIndex is zero-based.
If you're using a List or a Collection etc., it needs to be big enough, which is a nice waste of space. Basically, if you're doing manual paging, and you're using a List, you're going to have to create the List as big as the full record count of your result, and only fill in the proper page. Not very practical, and quite wasty, but it's simple enough.
Apart from creating your own pageable data source, there's also another, nicer way. You can use the AllowCustomPaging property to specify that you're already passing paged data. Just set VirtualItemCount to the record count, and pass just the one page in the DataSource and call DataBind as usual. That should do :)
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 so many list of ServerName in GridView, so I decide to add paging. The data show list result on page 1 but on page 2 and the rest of it is not display anything. I already have OnPageIndexChanging="GridViewServer_PageIndexChanging" in GridViewServer property. Please help! Here is c# code behind,
protected void GridViewServer_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
GridViewServer.PageIndex = e.NewPageIndex;
GridViewServer.DataBind();
}
A GridView binding function codes,
public void BindGridView()
{
SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["Database_Shared_NotebookConnectionString"].ConnectionString);
conn.Open();
string sqlquery = ("SELECT * FROM tblServer");
SqlCommand command = new SqlCommand(sqlquery, conn);
SqlDataAdapter adp = new SqlDataAdapter(command);
DataSet ds = new DataSet();
adp.Fill(ds);
GridViewServer.DataSource = ds.Tables[0];
GridViewServer.DataBind();
}
You need to set your GridView's datasource appropriately. You can't just call DataBind if the datasource isn't properly set. Basically what it amounts to is binding your GridView to null (which would have no page 2). I would recommend having a private method that is responsible for this process and whenever you need to bind you call that.
private void BindGridViewServer()
{
GridViewServer.DataSource = GetYourData(); // This should get the data
GridViewServer.DataBind();
}
Call this method from within your event with:
protected void GridViewServer_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
GridViewServer.PageIndex = e.NewPageIndex;
BindGridViewServer();
}
This could be made more extensible by passing in the GridView as a parameter, but you'd have to have other parameters as well to make sure the method retrieves the proper data.
Here's a very good tutorial (with sample code) on custom GridView paging. This makes the paging controls look like the familiar ones you see on a lot of search engines, forums, etc.
http://geekswithblogs.net/aghausman/archive/2009/05/18/custom-paging-in-grid-view.aspx
You have to give datasource to GridViewServer every time on page index changed.
so the code would be like this
protected void GridViewServer_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
GridViewServer.PageIndex = e.NewPageIndex;
GridViewServer.Datasource = MethodReturningDataTable();
GridViewServer.DataBind();
}
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
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;
}