ASP.Net Compilation Error for GridView OnPageIndexChanging event - asp.net

Before I add this codes, I got error about GridView fired event PageIndexChanging which wasn't handled and same for Sorting. So I add this event codes then I got Compilation error say that, "CS1061: 'ASP.serveredit_aspx' does not contain a definition for 'GridViewServer_PageIndexChanging' and no extension method 'GridViewServer_PageIndexChanging' accepting a first argument of type 'ASP.serveredit_aspx' could be found". However I already have that event code in C# as well. Please Help
Here my GridView property codes,
<asp:GridView ID="GridViewServer" runat="server" AllowPaging="True" AllowSorting="True" OnPageIndexChanging="GridViewServer_PageIndexChanging" OnSorting="GridViewServer_Sorting" AutoGenerateColumns="False" BackColor="White" BorderColor="#CCCCCC" BorderStyle="None" BorderWidth="1px" CellPadding="3" DataKeyNames="ServerName" GridLines="None" ShowFooter="True" onrowcancelingedit="GridViewServer_RowCancelingEdit"
onrowdeleting="GridViewServer_RowDeleting" onrowediting="GridViewServer_RowEditing"
onrowupdating="GridViewServer_RowUpdating">
The C# code behind for this event,
private string ConvertSortDirectionToSql(SortDirection sortDirection)
{
string newSortDirection = String.Empty;
switch (sortDirection)
{
case SortDirection.Ascending:
newSortDirection = "ASC";
break;
case SortDirection.Descending:
newSortDirection = "DESC";
break;
}
return newSortDirection;
}
protected void gridViewServer_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
GridViewServer.PageIndex = e.NewPageIndex;
GridViewServer.DataBind();
}
protected void gridViewServer_Sorting(object sender, GridViewSortEventArgs e)
{
DataTable dataTable = GridViewServer.DataSource as DataTable;
if (dataTable != null)
{
DataView dataView = new DataView(dataTable);
dataView.Sort = e.SortExpression + " " + ConvertSortDirectionToSql(e.SortDirection);
GridViewServer.DataSource = dataView;
GridViewServer.DataBind();
}
}

I realize the gridViewServer_PageIndexChanging and gridViewServer_Sorting are lower case. I forgot to capitalize it.

Related

Data Going Out of Synch when using GridView inside UpdatePanel

Data in my GridView inside an UpdatePanel is going out of synch with the database and I can't figure out why. This has resulted in incorrect updates to the database which I have to fix rapidly! Can anyone help?
I have multiple UpdatePanels that have GridViews inside that can be edited by the user. There is a search feature and filter buttons that select queried data from the database and display in the GridView. There is sorting enabled and the "out of synchness" occurs mostly when sorting and then editing a field.
The data comes from a SQL Database. I can update the data directly through OnTextChange option of my TemplateField like this:
<asp:GridView
ID="GridView4"
runat="server"
OnSorting="TaskGridView_Sorting"
AllowSorting="True"
Width="100%" >
<Columns>
<asp:TemplateField SortExpression="name" HeaderText="Name">
<HeaderStyle HorizontalAlign="Left" CssClass="col_name" />
<ItemTemplate>
<asp:TextBox ID="name" AutoPostBack="True" CssClass="col_name" runat="server" Text='<%# Eval("name") %>' Width=180 OnTextChanged="text_change" />
</ItemTemplate>
</asp:TemplateField>
...
I have my gridview inside an UpdatePanel that has these options:
<asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional">
<ContentTemplate>
...
I have enabled partial rendering like this:
<ajaxToolKit:ToolkitScriptManager EnablePartialRendering="true" runat="server" />
I have buttons that filter the data by requerying the database and displaying just the filtered data like this:
DataGrid_Load(DAL.Search_reg_log(OrgText.Text, searchText, searchCol), "reg");
The gridview gets its data loaded like this:
private void DataGrid_Load(DataTable command, string type)
{
DataTable dataTable = new DataTable();
dataTable = command;
string sortDir = ViewState["SortDirection"] as string;
string sortExp = ViewState["SortExpression"] as string;
if(ViewState["SortExpression"] != null)
{
dataTable = resort(dataTable, sortExp, sortDir);
}
try
{
var query = from c in dataTable.AsEnumerable()
where c.Field<string>("status") == "Invoiced" && c.Field<string>("reg_cat_id") != "Archive"
|| c.Field<string>("status") == "Confirmed" && c.Field<string>("reg_cat_id") != "Archive"
select c ;
if(query.Any()){
DataTable t2 = query.CopyToDataTable();
GridView4.DataSource = t2;
GridView4.DataBind();
} else {
GridView4.DataSource = new DataTable();
GridView4.DataBind();
}
}
catch(Exception e) {
ErrorText.Text = "Caught Exception: " + e;
}
...
I have isolated one cause of the data errors which occurs after sorting a column and then
protected void TaskGridView_Sorting(object sender, GridViewSortEventArgs e)
{
string sortExp = ViewState["SortExpression"] as string;
string sortDir = ViewState["SortDirection"] as string;
if(sortDir == "asc" & sortExp == e.SortExpression.ToString())
ViewState["SortDirection"] = "desc";
else
ViewState["SortDirection"] = "asc";
ViewState["SortExpression"] = e.SortExpression.ToString();
if(searchCol != "" && searchText != "")
DataGrid_Load(DAL.Search_reg_log(OrgText.Text, searchText, searchCol), "reg");
else
DataGrid_Load(DAL.reg_log(HeadText.Text, OrgText.Text), "reg");
UpdatePanels();
}
Here is the resort function:
public static DataTable resort(DataTable dt, string colName, string direction)
{
dt.DefaultView.Sort = colName + " " + direction;
dt = dt.DefaultView.ToTable();
return dt;
}
Please help with some direction of what might be causing this.
It looks like you are having some trouble with GridView and updating them. I will post a complete working example below. Start with that and gradually update that code to fit your own needs, like getting data with var query = from c in dataTable.AsEnumerable(). The important thing is to sort the data every time you (re)bind the GridView data. And I'm not sure what is happening inside resort, but you have to use dt.DefaultView.ToTable(); to save the sorting in the DataTable.
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<asp:GridView ID="GridView1" runat="server"
DataKeyNames="ID" AllowSorting="true"
OnSorting="GridView1_Sorting"
AutoGenerateColumns="false"
AutoGenerateEditButton="true"
OnRowEditing="GridView1_RowEditing"
OnRowCancelingEdit="GridView1_RowCancelingEdit"
OnRowUpdating="GridView1_RowUpdating">
<Columns>
<asp:TemplateField HeaderText="ID" SortExpression="ID">
<ItemTemplate>
<%# Eval("ID") %>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Name" SortExpression="name">
<ItemTemplate>
<%# Eval("name") %>
</ItemTemplate>
<EditItemTemplate>
<asp:TextBox ID="TextBox1" runat="server" Text=' <%# Eval("name") %>'></asp:TextBox>
</EditItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
<asp:Literal ID="Literal1" runat="server"></asp:Literal>
</ContentTemplate>
</asp:UpdatePanel>
Code behind
protected void Page_Load(object sender, EventArgs e)
{
//bind data in an ispostback check
if (!IsPostBack)
{
DataGrid_Load();
}
}
private void DataGrid_Load()
{
//load the datatable data
DataTable dt = source;
//check if the viewsstate existst
if (ViewState["SortExpression"] != null && ViewState["SortDirection"] != null)
{
//sort the datatable before binding it to the gridview
dt.DefaultView.Sort = ViewState["SortExpression"] + " " + ViewState["SortDirection"];
dt.DefaultView.ToTable();
}
//bind the sorted datatable to the gridvidw
GridView1.DataSource = dt;
GridView1.DataBind();
}
protected void GridView1_Sorting(object sender, GridViewSortEventArgs e)
{
//load the previous sorting settigns
string sortExp = ViewState["SortExpression"] as string;
string sortDir = ViewState["SortDirection"] as string;
//reverse the direction if the column is the same as the previous sort
if (sortDir == "asc" & sortExp == e.SortExpression.ToString())
ViewState["SortDirection"] = "desc";
else
ViewState["SortDirection"] = "asc";
//put the current sort column in the viewstate
ViewState["SortExpression"] = e.SortExpression.ToString();
//rebind data
DataGrid_Load();
}
protected void GridView1_RowEditing(object sender, GridViewEditEventArgs e)
{
//set the edit index and rebind data
GridView1.EditIndex = e.NewEditIndex;
DataGrid_Load();
}
protected void GridView1_RowCancelingEdit(object sender, GridViewCancelEditEventArgs e)
{
//reset the edit index and rebind data
GridView1.EditIndex = -1;
DataGrid_Load();
}
protected void GridView1_RowUpdating(object sender, GridViewUpdateEventArgs e)
{
//use findcontrol to locate the textbox in the edit template
TextBox tb = (TextBox)GridView1.Rows[e.RowIndex].FindControl("TextBox1");
//get the id of the row from the datakeys
int id = Convert.ToInt32(GridView1.DataKeys[e.RowIndex].Values[0]);
//show result for testing
Literal1.Text = "ID: " + id + "<br>Name: " + tb.Text;
//reset the edit index and rebind data
GridView1_RowCancelingEdit(null, null);
}

A field or property with the name 'bname' was not found on the selected data source

I know this type of question has been asked multiple times, with solved answers. I've tried them all, but none of it seems to work. Please have a look and maybe help me in understanding where I am going wrong.
.aspx
<asp:view ID="view2" runat="server">
<asp:GridView ID="gvBatches" runat="server" AutoGenerateColumns="False" CssClass="table-hover table" GridLines="None" Width="900px" ShowFooter="True" >
<columns>
<asp:BoundField DataField="bname" HeaderText="Batch Name" />
</columns>
</asp:GridView>
</asp:view>
.aspx.cs
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
if (ViewState["query"] == null)
{
ViewState["query"] = "select course from tblCourses";
}
if (MultiView1.ActiveViewIndex == '1')
{
bindgrid1();
}
bindgrid();
}
}
protected void bindgrid1()
{
SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["DBCS"].ConnectionString);
DataTable dt1 = new DataTable();
using (SqlDataAdapter sda = new SqlDataAdapter(ViewState["query"].ToString(), con))
{
sda.Fill(dt1);
}
gvBatches.DataSource = dt1;
gvBatches.DataBind();
}
if (e.CommandName == "viewbat")
{
ViewState["query"] = "select bname from tblBatches where course='" + e.CommandArgument.ToString() + "'";
MultiView1.ActiveViewIndex = 1;
}
Multiview index is changed when a LinkButton(commandName="viewbat") is clicked on a different GridView(gvCourses with datafield="course" and that works fine).
The code throws same error even if the query is changed to simple:
select * from tblBatches
Database design:
Database design is as shown, consists 'bname'

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();

GridView lost sorting after paging?

I got the below code from internet. It is working properly. I have added paging also. When I'm just sorting, it is working properly. When I am changing the page index, the sorting is lost.
Here is the client side code that set a gridview with 20 items per page, using the sort linked to the "GridView1_Sorting" method in the server side code.
Client side
<asp:GridView ID="GridView1" runat="server" DataKeyNames="eno" AutoGenerateColumns="False" PageSize="20" AllowPaging="True" AllowSorting="True" OnSorting="GridView1_Sorting" CellPadding="4">
<Columns>
<asp:TemplateField HeaderText="Employee no" SortExpression="eno">
<ItemTemplate>
<%#Eval("eno")%>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Emp name" SortExpression="empname">
<ItemTemplate>
<%#Eval("empname")%>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Salary" SortExpression="sal">
<ItemTemplate>
<%#Eval("sal")%>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
And now the server side code:
Server side
using System.Data.SqlClient;
using System.Configuration;
using System.IO;
public partial class _Default : System.Web.UI.Page
{
SqlConnection sqlcon = new SqlConnection(ConfigurationManager.ConnectionStrings["Con"].ConnectionString);
SqlCommand sqlcmd;
SqlDataAdapter da;
DataTable dt = new DataTable();
DataTable dt1 = new DataTable();
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
GridData();
}
}
void GridData()
{
sqlcmd = new SqlCommand("select * from emp", sqlcon);
sqlcon.Open();
da = new SqlDataAdapter(sqlcmd);
dt.Clear();
da.Fill(dt);
if (dt.Rows.Count > 0)
{
Session["dt"] = dt;
GridView1.DataSource = dt;
GridView1.DataBind();
}
}
private string GVSortDirection
{
get { return ViewState["SortDirection"] as string ?? "DESC"; }
set { ViewState["SortDirection"] = value; }
}
private string GetSortDirection()
{
switch (GVSortDirection)
{
case "ASC":
GVSortDirection = "DESC";
break;
//assign new direction as ascending order
case "DESC":
GVSortDirection = "ASC";
break;
}
return GVSortDirection;
}
protected void GridView1_Sorting(object sender, GridViewSortEventArgs e)
{
DataTable dataTable = (DataTable)Session["dt"];
if (dataTable != null)
{
DataView dataView = new DataView(dataTable);
string sortDirection = GetSortDirection();
dataView.Sort = e.SortExpression + " " + sortDirection;
GridView1.DataSource = dataView;
GridView1.DataBind();
}
}
protected void GridView1_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
GridView1.PageIndex = e.NewPageIndex;
GridData();
}
}
When you page, the PageIndexChanging event is called. This in turn runs the GridData() procedure, which sets the data source for the gridview to be a data table containing records from the emp table, with no particular sort order.
What you should do is to take the code that you've written in your GridView1_Sorting event-handler, and include this within the GridData routine, so that whenever the grid is populated with data - whether when the page first loads, when the page index is changed or when the gridview is sorted - the gridview is based on a sorted dataview, rather than an unsorted data table.
The way you are maintaining SortDirection using GetSortDirection, in same fashion maintain SortExpression.
Happy coding!!!
Have a look to this article, may you will get what you want

ASP.NET GridView SortedAscendingHeaderStyle does not work

My SortedAscendingHeaderStyle and SortedDescendingHeaderStyle is not working at all
<asp:GridView ID="grdProducts" runat="server" CssClass="grid" AllowPaging="True" AllowSorting="True" PageSize="100" EmptyDataText="No data to show"
onrowdatabound="grdProducts_RowDataBound" onrowediting="grdProducts_RowEditing" onsorting="grdProducts_Sorting" AutoGenerateEditButton="True">
<AlternatingRowStyle CssClass="even" />
<SortedAscendingHeaderStyle ForeColor="White" CssClass="sorted" />
<SortedDescendingHeaderStyle CssClass="sorted desc" />
</asp:GridView>
Rows are sorted correctly when headers are clicked, but when I inspect the header using FireBug, it only shows: (this is when sorted ascending)
<th scope="col">
Namekey
</th>
ForeColor and CssClass are not set at all.
Anyone has any idea what I am doing wrong?
EDIT: My C# code behind
protected void grdProducts_Sorting(object sender, GridViewSortEventArgs e)
{
if ((string)ViewState["SortColumn"] == e.SortExpression)
ViewState["SortDirection"] = ((string)ViewState["SortDirection"] == "") ? " DESC" : "";
else
{
ViewState["SortColumn"] = e.SortExpression;
ViewState["SortDirection"] = "";
}
}
protected override void OnPreRender(EventArgs e)
{
BindGrid();
base.OnPreRender(e);
}
private void BindGrid()
{
string query = "SELECT ... ORDER BY " + ViewState["SortColumn"] + ViewState["SortDirection"];
DataTable dt = SqlFunctions.Select(query);
grdProducts.DataSource = dt;
grdProducts.DataBind();
}
I'm not sure if SortedDescendingHeaderStyle works without code if you're not using an asp:SQLDataSource as your GridView data source. But a little coding can get you there.
You need to apply the CSS style manually to the header cell. You can do it in the Sorting event.
protected void grdProducts_Sorting(object sender, GridViewSortEventArgs e)
{
if ((string)ViewState["SortColumn"] == e.SortExpression)
{
ViewState["SortDirection"] = ((string)ViewState["SortDirection"] == "") ? " DESC" : "";
grdProducts.HeaderRow.Cells[GetColumnIndex( e.SortExpression )].CssClass = "AscendingHeaderStyle";
}
else
{
ViewState["SortColumn"] = e.SortExpression;
ViewState["SortDirection"] = "";
grdProducts.HeaderRow.Cells[GetColumnIndex( e.SortExpression )].CssClass = "DescendingHeaderStyle";
}
BindGrid();
}
private int GetColumnIndex( string SortExpression )
{
int i = 0;
foreach( DataControlField c in gvwCustomers.Columns )
{
if( c.SortExpression == SortExpression )
break;
i++;
}
return i;
}
I don't have enough rep to comment on the accepted answer. When I tried applying the solution, it would sort properly, but did not apply the CSS class to what was eventually rendered.
In my case, invoking DataBind() on my grid AFTER sorting my DataSource (List) and assigning it as the grid's DataSource, but BEFORE setting the CssClass did the trick. Figured I'd share in case someone else encountered something similar.
I think it's the timing of your databinding. Change your databinding to work like this:
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
BindGrid();
}
}
protected void grdProducts_Sorting(object sender, GridViewSortEventArgs e)
{
if ((string)ViewState["SortColumn"] == e.SortExpression)
ViewState["SortDirection"] = ((string)ViewState["SortDirection"] == "") ? " DESC" : "";
else
{
ViewState["SortColumn"] = e.SortExpression;
ViewState["SortDirection"] = "";
}
BindGrid();
}
GridView.Sorting Event
Super-late, but for reference. It works for me, using the following:
Here's my code (in x.aspx):
<asp:SqlDataSource ID="SqlDataSourceX" runat="server" ConnectionString="xxx"
EnableViewState="False" OnSelecting="SqlDataSourceXSelecting"></asp:SqlDataSource>
<asp:GridView ....
AllowSorting="True"
EnableSortingAndPagingCallbacks="False"
OnSorted="GridViewResults_OnSorted" .... DataSourceID="SqlDataSourceX" CssClass="table table-bordered text-left">
<SortedAscendingHeaderStyle CssClass="SortedAscendingHeaderStyle"></SortedAscendingHeaderStyle>
<SortedDescendingHeaderStyle CssClass="SortedDescendingHeaderStyle"></SortedDescendingHeaderStyle>
<Columns>
...
Here's my code (in x.aspx.cs):
protected void GridViewResults_OnSorted(object sender, EventArgs e) {
ExecuteSearch(); //Adds some where clauses to the SQL Data Source, no explicit sorting here
}
This then creates the following table headers, after clicking for sort:
<th class="SortedDescendingHeaderStyle" scope="col">
BUR Nummer
</th>

Resources