The GridView 'GridView1' fired event PageIndexChanging which wasn't handled - asp.net

I have created:
one master page and one content page called Detail.
On Button click event, displaying data in grid view.
In grid view, columns are autogenerated.
I wanted to show 11 column in grid view, but it is more than page
size.
What to do for this?
I have created sql helper file for database connection code and calling that method, not using sqldatasource for connection.
When I trying to do paging, getting error:
The GridView 'GridView1' fired event PageIndexChanging which wasn't
handled.

You need to declare a method on your code behind that handles the PageIndexChanging event.
Something similar to this:
protected void GridView1_PageIndexChanging (object sender, GridViewPageEventArgs e)
{
GridView1.PageIndex = e.NewPageIndex;
bindGridView(); //bindgridview will get the data source and bind it again
}
private void bindGridView()
{
GridView1.DataSource=getData();
GridView1.DataBind();
}
Providing sample code:
protected void GridView1_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
GridView1.PageIndex = e.NewPageIndex;
bindGridView(); //bindgridview will get the data source and bind it again
}
protected void Page_Load(object sender , EventArgs e)
{
if(!IsPostBack)
bindGridView();
}
//this is some sample data
private void bindGridView()
{
DataTable t = new DataTable();
t.Columns.Add("Col1");
t.Columns.Add("Col2");
DataRow r = null;
for (int i = 0; i < 25; i++)
{
r = t.NewRow();
r.ItemArray = new object[] { "Val" + i, " Another " + i };
t.Rows.Add(r);
}
GridView1.DataSource = t;
GridView1.DataBind();
}
And this is the markup:
<asp:GridView OnPageIndexChanging="GridView1_PageIndexChanging" AllowPaging="true" PageSize="10" ID="GridView1" runat="server" AutoGenerateColumns="true">
Produces this:

For Paging you can use OnPageIndexChanging for this....
For Example
you have to use OnPageIndexChanging="gvdetails_PageIndexChanging" in your GridView...
You have to write below code into event in code behind like
protected void gvdetails_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
gvdetails.PageIndex = e.NewPageIndex;
BindData();
}
For more detail you can check the below link here I am using page Index change in my article...
Here I use PageIndexChange
I hope this will helps you....Share it with others...Thanks!

This is the final answer:
Imports System.Collections.Generic ' library
Protected Sub grdEmployees_PageIndexChanging1(ByVal sender As Object, ByVal e As
System.Web.UI.WebControls.GridViewPageEventArgs) Handles grdEmployees.PageIndexChanging
grdEmployees.PageIndex = e.NewPageIndex
LoadEmployeeList() 'FUNCTION FOR DATASET
grdEmployees.DataBind()
End Sub

you simply add this to your code :
protected void GridViewTrsEmail_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
GridViewTrsEmail.PageIndex = e.NewPageIndex;
GridViewTrsEmail.DataBind();
}

To fix this, I had to take a closer look at my datasource and datakeys. I have a set of records that are returned from SQL Server and what I was doing is binding them to a POCO. This class had several public properties of type Integer. These Integers were my datakeys on the grid. I replaced their type with a string instead to bypass the casting issue.

Related

ASP.NET (4.5) GridView binding to dynamically-generated SQL query, with paging and sorting?

I'm using VS 2013 (latest version) and an ASP.NET 4.5 WebForms application. I need to run SQL commands that return data, but that's all I know about the SQL at runtime. I want to bind the result at runtime to a GridView and have it auto-generate columns. I also want it to support sorting and paging.
I've researched this ad nauseam, and I find tons of examples that refer to one part of this, but nothing that appears to allow all aspects at once.
Isn't there some easy way to do this? It would seem to me that I should just be able to bind the data to the grid, and let it take care of everything else.
FYI, the SQL commands in question are stored in a table in the database, along with information about parameters (if any). My web app allows the user to select one of these SQL commands, facilitates entering parameter information, and lets the user run the query to export it to different formats or even run a Crystal Report for it. So that's why I don't know anything about the SQL at runtime. In case you cared. :)
EDIT:
So here is what I came up with. Please note that I removed a bunch of code that is related to my logic that isn't really relevant to this discussion, so this may not compile, but it should give you the idea.
<asp:GridView runat="server" ID="gridView1" CssClass="XG_DataTable"
AllowSorting="true" AllowPaging="true" PageSize="20"
OnPageIndexChanging="gridView1_OnPageIndexChanging"
OnSorting="gridView1_OnSorting"
AutoGenerateColumns="true">
</asp:GridView>
...
public partial class ViewGrid
{
private bool SortAscending
{
get
{
var result = ViewState["SortAscending"];
return (result == null) || ((bool) result);
}
set { ViewState["SortAscending"] = value; }
}
private string SortExpression
{
get
{
var result = ViewState["SortExpression"];
return result == null ? "" : result.ToString();
}
set
{
if (value == SortExpression)
SortAscending = !SortAscending;
else
{
ViewState["SortExpression"] = value;
SortAscending = true;
}
}
}
protected void Page_Load(object sender, EventArgs e)
{
BindGridView();
}
private void BindGridView()
{
gridView1.DataSource = GetData();
gridView1.DataBind();
}
private object GetData()
{
var dataTable = GetUnsortedData();
var sortExpression = SortExpression;
if (string.IsNullOrEmpty(sortExpression))
return dataTable;
var dv = new DataView(dataTable);
dv.Sort = string.Format("{0} {1}", sortExpression, SortAscending ? "asc" : "desc");
return dv;
}
private DataTable GetUnsortedData()
{
// retrieve the data from the database
}
protected void gridView1_OnPageIndexChanging(object sender, GridViewPageEventArgs e)
{
gridView1.PageIndex = e.NewPageIndex;
BindGridView();
}
protected void gridView1_OnSorting(object sender, GridViewSortEventArgs e)
{
SortExpression = e.SortExpression;
BindGridView();
}
}
Here's a sample
HTMl markup:
<asp:GridView runat="server" AllowPaging="true" AllowSorting="true"
id="mygrid" AutoGenerateColumns="true"></asp:GridView>
You can set PageSize for number of rows from the data source to display per page.
C#
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
gvBind(); //Bind gridview
}
}
public void gvBind()
{ SqlDataAdapter dap = new SqlDataAdapter("select query", conn);
DataSet ds = new DataSet();
dap.Fill(ds);
mygrid.DataSource = ds.Tables[0];
mygrid.DataBind();
}
protected void PageIndexChanging(object sender, GridViewPageEventArgs e)
{
mygrid.PageIndex = e.NewPageIndex;
gvBind();
}
Get the data in a dataset and set the gridview datasource to that dataset.
Frontend
<asp:GridView runat="server" AllowPaging="true" AllowSorting="true" id="mygrid" AutoGenerateColumns="true"></asp:GridView>
Then code behind
mygrid.DataSource = dataset
mygrid.DataBind();

using selectcommand on code behind with gridview

I have a sqldatascource that I need to pass null values to it and then use the selectcommand specified by a stored procedure and then using the result query to populate a gridview on the page load
notes: I tried the stored procedure on sql server managment studio and its working fine
I alread specified sqldatascource on for gridview1 in the page design view
I tried this code but the gridview still shows empty
protected void Page_Load(object sender, EventArgs e)
{
SqlDataSource1.SelectParameters["location"].DefaultValue = null;
SqlDataSource1.SelectParameters["time"].DefaultValue = null;
SqlDataSource1.SelectParameters["date"].DefaultValue = null;
SqlDataSource1.DataBind();
GridView1.DataBind();
}
I think using null does not represent a database NULL.
This might work
protected void Page_Load(object sender, EventArgs e)
{
if(!Page.IsPostBack)
{
SqlDataSource1.SelectParameters["location"].DefaultValue = System.DbNull.Value;
SqlDataSource1.SelectParameters["time"].DefaultValue = System.DbNull.Value;
SqlDataSource1.SelectParameters["date"].DefaultValue = System.DbNull.Value;
SqlDataSource1.DataBind();
GridView1.DataBind();
}
}

Gridview AutoGeneratingColumn Event?

The .NET DataGrid control has an AutoGeneratingColumn Event that fires once for every bound data item right after the data source is changed. This is useful because you could define certain columns in the template, like so:
<Columns>
<asp:HyperLinkField DataNavigateUrlFields="ID" DataNavigateUrlFormatString="ww{0}" DataTextField="ID" DataTextFormatString="{0}" HeaderText="ID" />
</Columns>
and then prevent the same column from being replicated when columns are autogenerated from your data source. In this example, you could prevent the ID column from being autogenerated like this:
Private Sub DG_AutoGeneratingColumn(ByVal sender As Object, ByVal e As DataGridAutoGeneratingColumnEventArgs)
Dim headername As String = e.Column.Header.ToString()
If headername = "ID" Then
e.Cancel = True
End If
End Sub
My question is whether a similar functionality can be achieved with a GridView control.
DETAILS
The data source for the gridview is a DataTable object, which I am binding like so:
GridView1.DataSource = results.Tables("Vitals")
GridView1.DataBind()
The number of columns in my DataTable will vary, which is why it is extremely convenient for me to use AutoGenerateColumns.
To do that you should handle the RowCreated event and write something like the following:
private List<int> hideColumnsIndexes = new List<int>();
protected void Page_Load(object sender, EventArgs e)
{
hideColumnsIndexes.Clear();
}
protected void GridView1_OnRowCreated(object sender, GridViewRowEventArgs e)
{
//Find indexes
if (e.Row.RowType == DataControlRowType.Header)
{
for (int i = 0; i < e.Row.Cells.Count; i++ )
{
if (e.Row.Cells[i].Text == "Id")
{
hideColumnsIndexes.Add(i);
}
//Add more columns to hide
}
}
//Hide cells
foreach (var index in hideColumnsIndexes)
{
e.Row.Cells[index].Visible = false;
}
}

When to fill a sorted asp:GridView?

i've tried to ask this question a number of ways. It's a difficult question to answer because you have to understand what's going on.
When do i fill a GridView?
The nieve answer is during Page_Load, if not a PostBack:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
DataSet ds = GetStuffToShow();
GridView1.DataSource = ds;
GridView1.DataBind();
}
}
The problem with that is that if it is a postback, the grid is not filled. The reason the grid is not filled is because we've turned off the viewstate of the grid.
So don't look at IsPostBack
We need to always fill the grid, postback or not:
protected void Page_Load(object sender, EventArgs e)
{
DataSet ds = GetStuffToShow();
GridView1.DataSource = ds;
GridView1.DataBind();
}
The problem with that is that if the user sorts a column, the OnSorting event is called after both Page_Init and Page_Load:
protected void GridView1_Sorting(object sender, GridViewSortEventArgs e)
{
DataSet ds = GetStuffToShow(e.SortExpression, e.SortDirection);
GridView1.DataSource = ds;
GridView1.DataBind();
}
we've run two database queries, when only one was required.
Cache is fine for column sorting
If i'm willing to accept invalid cache during column sorting, i can store the DataSet in the session variable, as long as i invalidate it for any other operation.
The problem is the OnSorting event is called after i need it (Page_Load):
protected void Page_Load(object sender, EventArgs e)
{
if (AGridViewOnSortingEventIsntBeingRaised)
{
DataSet ds = GetStuffToShow();
StoreTheDatasetInTheSessionSomehowInCaseTheyCallSortInTheFuture(ds);
GridView1.DataSource = ds;
GridView1.DataBind();
}
}
protected void GridView1_Sorting(object sender, GridViewSortEventArgs e)
{
DataSet ds = GetDataSetOutOfSessionSomehowThatDamnWellBetterBeThere();
SomehowSortAReadOnlyDisconnectedDataSet(ds, e.SortExpression, e.SortDirection);
GridView1.DataSource = ds;
GridView1.DataBind();
}
Fear of the unknown
Then there's still the terror i have because i turned off viewstate of the GridView. i don't think that a read-only asp:GridView should need tens of kilobytes base64 encoded, when i can just rebuild it from the server (or from memory).
But i believe that i am obligated to return the GridView to the state it was in the last time the page was rendered. And i have to do it before Page_Load (i.e. during Page_Init). i have this fear because someone said so. So i turn it into
protected void Page_Init(object sender, EventArgs e)
{
if (AGridViewOnSortingEventIsntBeingRaised)
{
DataSet ds = GetStuffToShow();
StoreTheDatasetInTheSessionSomehowInCaseTheyCallSortInTheFuture(ds);
GridView1.DataSource = ds;
GridView1.DataBind();
}
}
The problem with this is that GetStuffToShow depends on things the user has typed into text boxes, which don't exist during Page_Init
Anyway, i'm rambling. It's too hot in here. Hopefully this question will be answered, unlike my other recent frustrations with asp.net
Bonus Reading
Sorting GridView Formed With Data Set
By adding a couple of hidden fields, one for the sort expression, and the other for the sort direction you can use those values to populate the GridView once at page load and then update the sorting in the Sorting event (sort code modified from the All-In-One Code Framework GridView sample):
protected void Page_Load(object sender, EventArgs e)
{
DataSet ds = GetStuffToShow();
GridView1.DataSource = ds;
GridView1.DataBind();
}
protected void GridView1_Sorting(object sender, GridViewSortEventArgs e)
{
// If the sorting column is the same as the previous one,
// then change the sort order.
if (SortExpression.Value.Equals(e.SortExpression))
{
SortDirection.Value = SortDirection.Value.Equals("ASC") ? "DESC" : "ASC";
}
// If sorting column is another column,
// then specify the sort order to "Ascending".
else
{
SortExpression.Value = e.SortExpression;
SortDirection.Value = "ASC";
}
var sortedView = new DataView(<convert your DataSet to a DataTable>)
{ Sort = string.Format("{0} {1}", this.SortExpression.Value, this.SortDirection.Value) };
GridView1.DataSource = sortedView;
GridView1.DataBind();
}
Note that SortDirection and SortExpression are the hidden fields. This also lends itself well to caching the DataSet.
Also, I wouldn't be concerned about the Page_Init issue that you brought up. That should only apply if you are dynamically creating your Controls.
A simple solution is to call Gridview.DataBind() on the Page.Pre_Render event, which makes it called after having handled any Button/Sorting, events. This a good way to ensure you call it only once per Request.
To make things clearer, it is also a good thing to access your dataset through a Property which will basically call your "Store-The-Dataset-In-The-Session-Somehow-In-Case-They-Call-Sort-In-The-Future" method in its Set part and your "Get-Data-Set-Out-Of-Session-That-Had-Better-Be-There" in the Get part.
You may try to fill the grid on Gridview Needdatasource event
it will be called when ever you perform a postback and get the proper functionality what ever you code in the event.
also if you want to bind it again you can just data databind method and that will call the needdatasource event again

gridview event: no overload matches delegate

Here's the problem with the gridview as I have it:
in the aspx:
<asp: GridView..... ID="MyGrid" AllowSorting = "True" OnSorting = "SortMyGrid">
in the code behind:
protected void SortMyGrid(object sender, GridViewPageEventArgs e)
{
DataTable TheGridData = MyGrid.DataSource as DataTable;
}
And then when I run the code:
No overload for 'SortMyGrid' matches delegate
What's causing this problem?
Thanks.
You have the wrong EventArgs you need to be using GridViewSortEventArgs not GridViewPageEventArgs
MSDN Article GridView Sorting Event

Resources