sort Gridview doesn't work - c#

I have asp.net page contain gridview as following
<asp:GridView ID="GridView1" runat="server" AllowPaging="True"
OnPageIndexChanging="gridView_PageIndexChanging"
OnSorting="TaskGridView_Sorting"
AllowSorting="True" AutoGenerateColumns="False"
onselectedindexchanged="GridView1_SelectedIndexChanged"
BackColor="#DEBA84" BorderColor="#DEBA84" BorderStyle="None" BorderWidth="1px"
CellPadding="3" CellSpacing="2">
<RowStyle BackColor="#FFF7E7" ForeColor="#8C4510" />
<Columns>
<asp:boundfield datafield="name_english" convertemptystringtonull="true" headertext="Name"/>
<asp:BoundField DataField="Inc_ID" convertemptystringtonull="true" HeaderText="Inc_ID" SortExpression="Inc_ID"/>
<asp:BoundField DataField="UID" HeaderText="Study_UID" SortExpression= "UID"/>
</Columns>
<FooterStyle BackColor="#F7DFB5" ForeColor="#8C4510" />
<PagerStyle ForeColor="#8C4510" HorizontalAlign="Center" />
<SelectedRowStyle BackColor="#738A9C" Font-Bold="True" ForeColor="White" />
<HeaderStyle BackColor="#A55129" Font-Bold="True" ForeColor="White" />
</asp:GridView>
I fill and sort it using the following code
protected void Button1_Click(object sender, EventArgs e)
{
//connection to database
string connection = System.Configuration.ConfigurationManager.ConnectionStrings["NorthindConnectionString"].ConnectionString;
SqlConnection myConn = new SqlConnection(connection);
myConn.Open();
SqlCommand cmd = new SqlCommand(" WorkList", myConn);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add(new SqlParameter("#Name", TextBox1.Text));
cmd.Parameters.Add(new SqlParameter("#ID", TextBox2.Text));
cmd.Parameters.Add(new SqlParameter("#AccNo", TextBox4.Text));
SqlDataAdapter da = new SqlDataAdapter(cmd);
DataSet ds = new DataSet();
da.Fill(ds);
GridView1.DataSource = ds;
GridView1.DataBind();
Session["TaskTable"] = ds.Tables[0];
ds.Dispose();
da.Dispose();
GridView1.Visible = true;
myConn.Close();
}
protected void TaskGridView_Sorting(object sender, GridViewSortEventArgs e)
{
//Retrieve the table from the session object.
DataTable dt = Session["TaskTable"] as DataTable;
if (dt != null)
{
//Sort the data.
dt.DefaultView.Sort = e.SortExpression + " " + GetSortDirection(e.SortExpression);
GridView1.DataSource = Session["TaskTable"];
GridView1.DataBind();
}
}
private string GetSortDirection(string column)
{
// By default, set the sort direction to ascending.
string sortDirection = "ASC";
// Retrieve the last column that was sorted.
string sortExpression = ViewState["SortExpression"] as string;
if (sortExpression != null)
{
// Check if the same column is being sorted.
// Otherwise, the default value can be returned.
if (sortExpression == column)
{
string lastDirection = ViewState["SortDirection"] as string;
if ((lastDirection != null) && (lastDirection == "ASC"))
{
sortDirection = "DESC";
}
}
}
// Save new values in ViewState.
ViewState["SortDirection"] = sortDirection;
ViewState["SortExpression"] = column;
return sortDirection;
}
}
the problem when click on any header for sorting raise error System.IndexOutOfRangeException: Cannot find column name .. , any idea to solve that , I am sure from the columns name in database ,

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 gridView_Sorting(object sender, GridViewSortEventArgs e)
{
DataTable dataTable = gridView.DataSource as DataTable;
if (dataTable != null)
{
DataView dataView = new DataView(dataTable);
dataView.Sort = e.SortExpression + " " + ConvertSortDirectionToSql(e.SortDirection);
gridView.DataSource = dataView;
gridView.DataBind();
}
}
try this code..

You need to bind your grid to the sorted view (and not the original table) for sorting to work.
protected void TaskGridView_Sorting(object sender, GridViewSortEventArgs e)
{
//Retrieve the table from the session object.
DataTable dt = Session["TaskTable"] as DataTable;
if (dt != null)
{
//Sort the data.
dt.DefaultView.Sort = e.SortExpression;
GridView1.DataSource = dt.DefaultView;
GridView1.DataBind();
}
}
I am not sure if you need GetSortDirection method.
Also note that SortExpression property consists of sort direction (e.g. "UID DESC") so base your logic on that. Your code could have set sort expression such as "UID DESC ASC" which is obviously a wrong expression.

In order to have the code work in asp.net or a web environment, you need to put your gridview in Session a session object, and your sorting in a view state. In order to get the sorting to work with paging, do the following.
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
Session["SearchTable"] = gv_GridView.DataSource;
LoadSearchGrid("Select * from WF_Search);
}
private void LoadSearchGrid(string query)
{
DataTable dsp = new DataTable();
conn = new SqlConnection(ConnectionString);
SqlDataAdapter sda = new SqlDataAdapter(query, conn);
conn.Open();
sda.Fill(dsp);
Session["SearchTable"] = dsp;
gv_GridView.DataSource = Session["SearchTable"];
gv_GridView.DataBind();
conn.Close();
sda.Dispose();
}
protected void gv_GridView_Sorting(object sender, GridViewSortEventArgs e)
{
ViewState["SortDirection"] = e.SortDirection;
DataTable dtr = Session["SearchTable"] as DataTable;
if (dtr != null)
{
dtr.DefaultView.Sort = e.SortExpression + " " + getSortDirection(e.SortExpression);
gv_GridView.DataSource = Session["SearchTable"];
gv_GridView.DataBind();
Session["SearchTable"] = gv_GridView.DataSource;
}
}
private string getSortDirection(string column)
{
string sortDirection = "ASC";
string sortExpression = ViewState["SortDirection"] as string;
if (sortExpression != null)
{
if (sortExpression == column)
{
string lastDirection = ViewState["SortDirection"] as string;
if (lastDirection != null && lastDirection == "ASC")
{
sortDirection = "DESC";
}
}
}
ViewState["SortDirection"] = sortDirection;
ViewState["SortExpression"] = column;
return sortDirection;
}
protected void gv_GridView_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
gv_GridView.DataSource = Session["SearchTable"];
gv_GridView.DataBind();
gv_GridView.PageIndex = e.NewPageIndex;
}

Related

Date columns will not sort on Gridview filled from DataTable

I am using this example to sort GridView loaded from DataTable. I also reviewed this post - I used sajanyamaha advice by adding columns to DataTable and that's when GridView's date columns starting sorting properly with one peculiarity. I have 11 columns, first column is a selectcommand that redirects to another page. I have no boundfields or template fields, gridview is filled from datatable in code behind.
The problem is sorting and paging work fine on all columns EXCEPT the 2 Date columns. The Date columns, ReviewDue and SubmittedDate. They sort correctly but they do not retain the sort order while paging. GridView will reset to page 1 at each sort column change which causes the user to never see past page 1 when Date column is sorted. The issue I am trying to resolve and understand is why do all the other columns function correctly but the Date columns behave differently? What custom handling is needed to get date columns to behave like the other string or int columns?
I have googled plenty but I don't find anything with this oddity.
Here is my pertinent code.
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
ViewState["SortExpr"] = "EPRID";
ViewState["SortDir"] = " DESC";
if (blnIsAdmin == true || blnIsManager == true)
{
BindData();
}
else
{
//redirect
Response.Redirect("~/ErrorPages/AccessDenied.aspx");
}
}
}
private void BindData()
{
GridView1.DataSource = this.GetData();
GridView1.DataBind();
}
private DataTable GetData()
{
string cmdStr = "SELECT * FROM ….ORDER BY " + ViewState["SortExpr"].ToString() + " " + ViewState["SortDir"].ToString();
DataTable table = new DataTable();
table.Columns.Add("EPRID", typeof(Int32));
table.Columns.Add("FormName", typeof(String));
table.Columns.Add("Name", typeof(String));
table.Columns.Add("Completed", typeof(Boolean));
table.Columns.Add("Sup1", typeof(String));
table.Columns.Add("Sup2", typeof(String));
table.Columns.Add("Sup3", typeof(String));
table.Columns.Add("ReviewDue", typeof(DateTime));
table.Columns.Add("SubmittedDate", typeof(DateTime));
table.Columns.Add("SubmittedBy", typeof(String));
table.Columns.Add("DocID", typeof(Int32));
using (SqlConnection conn = new SqlConnection(conStr))
{
using (SqlCommand cmd = new SqlCommand(cmdStr, conn))
{
cmd.CommandType = CommandType.Text;
//get all EPRs (unfiltered grid)
if (blnIsAdmin == true ")
{
cmdStr = "SELECT * FROM … ORDER BY " + ViewState["SortExpr"].ToString() + " " + ViewState["SortDir"].ToString();
using (SqlDataAdapter da = new SqlDataAdapter(cmdStr, conn))
{
da.Fill(table);
}
}
else if (blnIsManager == true)
{
cmdStr = "SELECT * FROM… WHERE user = #user …ORDER BY " + ViewState["SortExpr"].ToString() + " " + ViewState["SortDir"].ToString();
using (SqlDataAdapter da = new SqlDataAdapter(cmdStr, conn))
{
da.SelectCommand.Parameters.Add(new SqlParameter { ParameterName = "#user", Value = strCurrentUser, SqlDbType = SqlDbType.VarChar, Size = 50 });
da.Fill(table);
}
}
}
}
return table;
}
protected void GridView1_Sorting(object sender, GridViewSortEventArgs e)
{
//go to page 1 when sorting
GridView1.PageIndex = 0;
string sortExpression = e.SortExpression;
if (GridViewSortDirection == SortDirection.Ascending)
{
GridViewSortDirection = SortDirection.Descending;
SortGridView(sortExpression, DESCENDING);
ViewState["SortDir"] = " DESC";
}
else
{
GridViewSortDirection = SortDirection.Ascending;
SortGridView(sortExpression, ASCENDING);
ViewState["SortDir"] = " ASC";
}
ViewState["SortExpr"] = sortExpression;
}
private void SortGridView(string sortExpression, string direction)
{
ViewState["SortExpr"] = sortExpression;
ViewState["SortDir"] = direction;
//get unfiltered grid
DataTable dt = GetData();
DataView dv = new DataView(dt);
dv.Sort = sortExpression + direction;
GridView1.DataSource = dv;
GridView1.DataBind();
}
public SortDirection GridViewSortDirection
{
get
{
if (ViewState["sortDirection"] == null)
//ViewState["sortDirection"] = SortDirection.Ascending;
ViewState["sortDirection"] = SortDirection.Descending;
return (SortDirection)ViewState["sortDirection"];
}
set { ViewState["sortDirection"] = value; }
}
protected void GridView1_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
GridView1.PageIndex = e.NewPageIndex;
BindData();
}
<asp:GridView ID="GridView1" runat="server"
onselectedindexchanged="GridView1_SelectedIndexChanged"
AllowPaging="True"
AllowSorting="True"
Caption="List of awaiting or completed employee performance reviews"
PageSize="25"
onsorting="GridView1_Sorting"
onpageindexchanging="GridView1_PageIndexChanging"
CellPadding="4"
DataKeyNames="EPRID,DocID"
ForeColor="#333333" GridLines="None"
onrowcommand="GridView1_RowCommand"
onrowdatabound="GridView1_RowDataBound"
onselectedindexchanging="GridView1_SelectedIndexChanging"
CssClass="GridStyle" >
<RowStyle BackColor="#F7F6F3" ForeColor="Black" />
<Columns>
<asp:CommandField ShowSelectButton="True" />
</Columns>
<FooterStyle Font-Bold="True" ForeColor="Black" />
<PagerStyle ForeColor="Black" HorizontalAlign="Center" />
<SelectedRowStyle BackColor="#E2DED6" Font-Bold="True" ForeColor="#333333" />
<HeaderStyle BackColor="#5D7B9D" Font-Bold="True" ForeColor="Black" />
<EditRowStyle BackColor="#999999" />
<AlternatingRowStyle BackColor="White" ForeColor="#284775" />
</asp:GridView>
Solved! Part of the issue was with the SELECT statement in the view that was used in Sql query strings' FROM clause, cmdStr (details of this were left out of my original question for brevity-possibly my first error in getting proper help?). In the views' SELECT statement, the 2 datetime columns were constructed like this:
,Convert(varchar(10),NextReview,112) as ReviewDue
,Convert(varchar(10),SubmittedDate,112) as SubmittedDate
and should have been simply:
,NextReview as ReviewDue
,SubmittedDate
,etc...
(BTW it made no differnce which standard I used, 101, 110, 111, 112...). Also the corresponding data types in the DataTable's Add() method should match as DateTimein GetData(). Finally I added a condition and modified the ORDER BY clause in the SQL inline query, cmdStr to:
//pass ViewState to variable for use in cmdStr when DateTime columns are sorted on
strExpression = ViewState["SortExpr"].ToString();
if (strExpression == "ReviewDue" || strExpression == "SubmittedDate")
{
cmdStr = "SELECT * FROM vwView ORDER BY CONVERT(DATE, " + strExpression + ", 120) " + ViewState["SortDir"].ToString();
}
else
{
//use original cmdStr
}
In the gridviews _RowDataBound() event I also formated the date to show Date part only in the grid like this:
//ReviewDue will never be null
e.Row.Cells[8].Text = Convert.ToDateTime(((DataRowView)e.Row.DataItem)["ReviewDue"]).ToString("d");
//SubmittedDate can be null, handle null
object dtmDate9 = ((DataRowView)e.Row.DataItem)["SubmittedDate"];
if (dtmDate9 == DBNull.Value)
{
e.Row.Cells[9].Text = String.Empty;
}
else
{
e.Row.Cells[9].Text = Convert.ToDateTime(((DataRowView)e.Row.DataItem)["SubmittedDate"]).ToString("d");
}

GridView cannot be delete value asp.net

protected void Page_Load(object sender, EventArgs e)
{
DataTable dt = new DataTable();
string VisitorManagementConnectionString = ConfigurationManager.ConnectionStrings["VisitorManagementConnectionString"].ConnectionString;
string strQuery = "select Id, ItemName, FoundAt, TimeIn, ImageName from LostFound order by ID";
SqlCommand cmd = new SqlCommand(strQuery);
SqlConnection con = new SqlConnection(VisitorManagementConnectionString);
SqlDataAdapter sda = new SqlDataAdapter();
cmd.CommandType = CommandType.Text;
cmd.Connection = con;
ViewState["dt"] = dt;
BindGrid();
try
{
con.Open();
sda.SelectCommand = cmd;
sda.Fill(dt);
GridView1.DataSource = dt;
GridView1.DataBind();
}
catch (Exception ex)
{
Response.Write(ex.Message);
}
finally
{
con.Close();
sda.Dispose();
con.Dispose();
dt.Dispose();
}
}
protected void BindGrid()
{
GridView1.DataSource = ViewState["dt"] as DataTable;
GridView1.DataBind();
}
protected void GridView1_SelectedIndexChanged(object sender, EventArgs e)
{
}
protected void BtnLose_Click(object sender, EventArgs e)
{
Response.Redirect("SecurityLost.aspx");
}
protected void OnRowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
string ID = e.Row.Cells[0].Text;
foreach (Button button in e.Row.Cells[5].Controls.OfType<Button>())
{
if (button.CommandName == "Delete")
{
button.Attributes["onclick"] = "if(!confirm('Do you want to delete " + ID + "?')){ return false; };";
}
}
}
}
protected void OnRowDeleting(object sender, GridViewDeleteEventArgs e)
{
int ID = Convert.ToInt32(e.RowIndex);
DataTable dt = ViewState["dt"] as DataTable;
dt.Rows[ID].Delete();
string VisitorManagementConnectionString = ConfigurationManager.ConnectionStrings["VisitorManagementConnectionString"].ConnectionString;
using (SqlConnection con = new SqlConnection(VisitorManagementConnectionString))
{
using (SqlCommand cmd = new SqlCommand("DELETE FROM LostFound WHERE ID = #ID"))
{
cmd.Parameters.AddWithValue("#ID", ID);
cmd.Connection = con;
con.Open();
cmd.ExecuteNonQuery();
con.Close();
}
}
BindGrid();
}
when i press delete button the row can be delete but when i reload the
page the row i deleted still appeal back and my database also never be
deleted.
Can someone guide me where am I going wrong?
<asp:GridView ID="GridView1" runat="server" OnRowDataBound = "OnRowDataBound" AutoGenerateColumns = "false" OnRowDeleting="OnRowDeleting" Font-Names = "Arial" Caption = "Lose & Found" OnSelectedIndexChanged="GridView1_SelectedIndexChanged">
<Columns>
<asp:BoundField DataField = "ID" HeaderText = "ID" />
<asp:BoundField DataField = "ItemName" HeaderText = "Item Name" />
<asp:BoundField DataField = "FoundAt" HeaderText = "Place" />
<asp:BoundField DataField = "TimeIn" HeaderText = "Time Found" />
<asp:ImageField DataImageUrlField = "ID" DataImageUrlFormatString = "Image.aspx?ImageID={0}" ControlStyle-Width = "100" ControlStyle-Height = "100" HeaderText = "Preview Image"/>
<asp:CommandField ShowDeleteButton="True" ButtonType="Button" />
</Columns>
</asp:GridView>
This my HTML file.
So from the comments we've established that the problem is that your ID is always 0.To make sure the ID comes through correctly you need to make two changes:
1.Change the Page_Load() event like this:
protected void Page_Load(object sender, EventArgs e)
{
if(!Page.IsPostBack)
{
//Cut and paste the code to bind to the GridView here
}
}
2.Add this code to the RowDeleting event:
protected void GridView1_RowDeleting(object sender, GridViewDeleteEventArgs e)
{
int id = Int32.Parse(GridView1.Rows[e.RowIndex].Cells[0].Text);
}

Gridview sorting when databinding from codebehind file

I am using asp.net web-form and gridview on several pages to display data. I bind gridview from codebehind file.
SO far i am able to use following code to bind datasource to gridview and also enable paging but i a facing problem to enable sorting on the same grid. Any point or help regarding how to enable paging to make it work with the below code.
I also have addition fields which are not part of this code which i use for additional functionality
onrowdatabound="GridView1_RowDataBound" onrowcommand="GridView1_RowCommand"
.ASPX File
<asp:GridView ID="GridView1" runat="server" AllowPaging="True" AutoGenerateColumns="False" DataKeyNames="ID"
Width="990px" BackColor="White" BorderColor="WhiteSmoke" BorderStyle="None" BorderWidth="0px" CellPadding="5"
Font-Names="Verdana" Font-Size="X-Small" ForeColor="Black" GridLines="Horizontal" PageSize="10" CssClass="myheader" AllowSorting="true"
onrowdatabound="GridView1_RowDataBound" onrowcommand="GridView1_RowCommand" onpageindexchanging="GridView1_PageIndexChanging" >
<Columns>
<asp:BoundField DataField="ID" HeaderText="ID" SortExpression="ID" />
<asp:BoundField DataField="FirstName" HeaderText="First Name" SortExpression="FirstName" />
<asp:BoundField DataField="LastName" HeaderText="Last Name" SortExpression="LastName" />
<asp:BoundField DataField="Date" HeaderText="Date" SortExpression="Date" DataFormatString="{0:yyyy/MM/dd}"/>
</Columns>
<FooterStyle BackColor="#CCCC99" ForeColor="Black" />
<HeaderStyle Height="32px" Font-Bold="True" ForeColor="White" HorizontalAlign="Left" BorderStyle="None" />
<PagerStyle BackColor="White" ForeColor="Black" HorizontalAlign="Right" />
<SortedAscendingCellStyle BackColor="#F7F7F7" />
<SortedAscendingHeaderStyle BackColor="#4B4B4B" />
<SortedDescendingCellStyle BackColor="#E5E5E5" />
<SortedDescendingHeaderStyle BackColor="#242121" />
<RowStyle BorderColor="#f5f5f5" BorderStyle="Notset"/>
</asp:GridView>
CODE BEHIND
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
GetDetails();
}
}
protected void GetDetails()
{
string strSql = "SELECT * FROM Test_Table Order by Date Desc ";
DataSet ds = DataProvider.Connect_Select(strSql);
GridView1.DataSource = ds;
GridView1.DataBind();
}
protected void GridView1_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
GridView1.PageIndex = e.NewPageIndex;
GetDetails();
}
UPDATE: Code updated to
.ASPX
OnSorting="GridView1_OnSorting"
CODE BEHIND
protected void GridView1_OnSorting(object sender, GridViewSortEventArgs e)
{
string strSql = "SELECT * FROM Test_Table ";
DataSet ds = DataProvider.Connect_Select(strSql);
DataTable dataTable = ds.Tables[0];
DataTable dataTable = ds.Tables[0];
if (dataTable != null)
{
DataView dataView = new DataView(dataTable);
dataView.Sort = e.SortExpression + " "+e.SortDirection;
GridView1.DataSource = dataView;
GridView1.DataBind();
}
}
You should create sorting event like this :
protected void GridView1_OnSorting(object sender, GridViewSortEventArgs e)
{
//TODO write tour code here to get data from database;
DataTable dataTable = your datatable get from your db;
if (dataTable != null)
{
if (e.SortDirection.ToString() == "Ascending")
{
dataView.Sort = e.SortExpression + " ASC";
}
else if (e.SortDirection.ToString() == "Descending")
{
dataView.Sort = e.SortExpression + " DESC";
}
DataView dataView = new DataView(dataTable);
dataView.Sort = e.SortExpression + " "+e.SortDirection;
GridView1.DataSource = dataView;
GridView1.DataBind();
}
}
**e.SortExpression** provides sorting column name
**e.SortDirection** provides sorting direction like ASC or DESC.
Also you can take sort direction in view state on page
private string GridViewSortDirection
{
get { return ViewState["SortDirection"] as string ?? "DESC"; }
set { ViewState["SortDirection"] = value; }
}
private void SetSortDirection()
{
GridViewSortDirection = (GridViewSortDirection.ToUpper() == "DESC") ? "ASC" : "DESC";
}
I hope above code help you.
SOLUTION
I have deleted the old code it had a bug as sorting was not working properly when one us to move back and forth from one page to another. Below code is test and is working well with sorting & paging.
public partial class _Default : System.Web.UI.Page
{
string Sort_Direction = "Date DESC";
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
// GetRegistrationDetails();
ViewState["SortExpr"] = Sort_Direction;
DataView dv = Getdata();
GridView1.DataSource = dv;
GridView1.DataBind();
}
}
private DataView Getdata()
{
string strSql = "SELECT * ROM TEST_Table ";
DataSet ds = DataProvider.Connect_Select(strSql);
DataView dv = ds.Tables[0].DefaultView;
dv.Sort = ViewState["SortExpr"].ToString();
return dv;
}
protected void GridView1_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
GridView1.PageIndex = e.NewPageIndex;
DataView dv = Getdata();
GridView1.DataSource = dv;
GridView1.DataBind();
}
protected void GridView1_OnSorting(object sender, GridViewSortEventArgs e)
{
GridView1.PageIndex = 0;
string[] SortOrder = ViewState["SortExpr"].ToString().Split(' ');
if (SortOrder[0] == e.SortExpression)
{
if (SortOrder[1] == "ASC")
{
ViewState["SortExpr"] = e.SortExpression + " " + "DESC";
}
else
{
ViewState["SortExpr"] = e.SortExpression + " " + "ASC";
}
}
else
{
ViewState["SortExpr"] = e.SortExpression + " " + "ASC";
}
GridView1.DataSource = Getdata();
GridView1.DataBind();
}
}
You have already set AllowSorting="true" and the SortExpression property for each column, so the next step is keeping the last sort expression and sort direction between postbacks, and using them in PageIndexChanging and Sorting event.
I would suggest using ViewState to keep the last sort expression and sort direction
private string SortExpression
{
get
{
return ViewState["SortExpression"] == null ? string.Empty : ViewState["SortExpression"].ToString();
}
set
{
ViewState["SortExpression"] = value;
}
}
private string SortDirection
{
get
{
return ViewState["SortDirection"] == null ? string.Empty : ViewState["SortDirection"].ToString();
}
set
{
ViewState["SortDirection"] = value;
}
}
This is the method to get the next sort direction:
private string GetSortDirection(string sortExpression)
{
if (sortExpression == this.SortExpression)
{
// reverse the sort direction when current sort expression is the same as the last time
if (this.SortDirection == "ASC")
{
return "DESC";
}
else
{
return "ASC";
}
}
else
{
// always return ASC when current sort expression is different than the last time
return "ASC";
}
}
GetDetails method will need to know the sort expression and sort direction, so add sortExpression and sortDirection parameter:
protected void GetDetails(string sortExpression, string sortDirection)
{
string strSql = string.Format("SELECT * FROM Test_Table Order by {0} {1}", sortExpression, sortDirection);
DataSet ds = DataProvider.Connect_Select(strSql);
GridView1.DataSource = ds;
GridView1.DataBind();
// save current sort expression and sort direction to ViewState
this.SortExpression = sortExpression;
this.SortDirection = sortDirection;
}
Make sure you add OnSorting="GridView1_Sorting" to GridView1 markup code:
<asp:GridView ID="GridView1" runat="server" AllowPaging="True" AutoGenerateColumns="False" DataKeyNames="ID"
Width="990px" BackColor="White" BorderColor="WhiteSmoke" BorderStyle="None" BorderWidth="0px" CellPadding="5"
Font-Names="Verdana" Font-Size="X-Small" ForeColor="Black" GridLines="Horizontal" PageSize="10" CssClass="myheader" AllowSorting="true"
OnRowDataBound="GridView1_RowDataBound" OnRowCommand="GridView1_RowCommand" onpageindexchanging="GridView1_PageIndexChanging"
OnSorting="GridView1_Sorting" >
Assuming that the default sort expression is Date and the default sort direction is DESC, this is what Page_Load, GridView1_PageIndexChanging, and GridView1_Sorting methods will look like
private const string DEFAULT_SORT_EXPRESSION = "Date";
private const string DEFAULT_SORT_DIRECTION = "DESC";
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
GetDetails(DEFAULT_SORT_EXPRESSION, DEFAULT_SORT_DIRECTION);
}
}
protected void GridView1_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
GridView1.PageIndex = e.NewPageIndex;
// use the last sort expression and sort direction
GetDetails(this.SortExpression, this.SortDirection);
}
protected void GridView1_Sorting(object sender, GridViewSortEventArgs e)
{
// get next sort direction
string sortDirection = GetSortDirection(e.SortExpression);
// get data with current sort expression and sort direction
GetDetails(e.SortExpression, sortDirection);
}
UPDATE
If you want to go to page 1 when sorting, just add GridView1.PageIndex = 0; to GridView1_Sorting:
protected void GridView1_Sorting(object sender, GridViewSortEventArgs e)
{
GridView1.PageIndex = 0;
// get next sort direction
string sortDirection = GetSortDirection(e.SortExpression);
// get data with current sort expression and sort direction
GetDetails(e.SortExpression, sortDirection);
}

Sorting in gridview is not working

I am trying Sorting functionality in Grid view but its not working.Can some body help?
Code:
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 DataSet FillDataSet()
{
string source = "Database=GridTest;Server=Localhost;Trusted_Connection=yes";
con = new SqlConnection(source);
cmd = new SqlCommand("proc_mygrid", con);
ds = new DataSet();
da = new SqlDataAdapter(cmd);
da.Fill(ds);
GridView1.DataSource = ds;
GridView1.DataBind();
return ds;
}
protected void GridView1_Sorting(object sender, GridViewSortEventArgs e)
{
DataTable dt = GridView1.DataSource as DataTable;
if (dt != null)
{
DataView dv = new DataView(dt);
dv.Sort = e.SortExpression + " " + ConvertSortDirectionToSql(e.SortDirection);
GridView1.DataSource = dv;
GridView1.DataBind();
}
Here dt is coming null.why? pls help thanks.
EDIT:
enter code here <asp:GridView ID="GridView1" runat="server" CellPadding="4" ForeColor="#333333"
GridLines="None" AllowPaging="true" AllowSorting="true" PageSize="12"
onpageindexchanging="GridView1_PageIndexChanging"
onsorting="GridView1_Sorting">
EDIT(Total code)
public partial class _Default : System.Web.UI.Page
{
SqlConnection con;
SqlCommand cmd;
DataSet ds;
SqlDataAdapter da;
protected void Page_Load(object sender, EventArgs e)
{
}
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 DataSet FillDataSet()
{
string source = "Database=GridTest;Server=Localhost;Trusted_Connection=yes";
con = new SqlConnection(source);
cmd = new SqlCommand("proc_mygrid", con);
ds = new DataSet();
da = new SqlDataAdapter(cmd);
da.Fill(ds);
GridView1.DataSource = ds;
GridView1.DataBind();
return ds;
}
protected void GetValues(object sender, EventArgs e)
{
FillDataSet();
}
protected void GridView1_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
int newPagenumber = e.NewPageIndex;
GridView1.PageIndex = newPagenumber;
GridView1.DataSource = FillDataSet();
GridView1.DataBind();
}
protected void GridView1_Sorting(object sender, GridViewSortEventArgs e)
{
DataSet ds = FillDataSet();
DataTable dt = ds.Tables[0];
if (dt != null)
{
dt.DefaultView.Sort = e.SortExpression + " " + ConvertSortDirectionToSql(e.SortDirection);
GridView1.DataSource = dt;
GridView1.DataBind();
}
CODE:
private string GetSortDirection(string column)
{
string sortDirection = "DESC";
string sortExpression = ViewState["SortExpression"] as string;
if (sortExpression != null)
{
if (sortExpression == column)
{
string lastDirection = ViewState["SortDirection"] as string;
if ((lastDirection != null) && (lastDirection == "DESC"))
{
sortDirection = "ASC";
}
}
}
ViewState["SortDirection"] = sortDirection;
ViewState["SortExpression"] = column;
return sortDirection;
}
protected void GridView1_Sorting(object sender, GridViewSortEventArgs e)
{
DataTable dt = ((DataSet)Session["myDataSet"]).Tables[0];
dt.DefaultView.Sort = e.SortExpression + " " + GetSortDirection(e.SortExpression);
GridView1.DataSource = dt;
GridView1.DataBind();
}
Because you're setting a DataSet as DataSource and then casting it to DataTable with the operator as.
The 'as' operator in C# is a tentative cast - if it's impossible to cast (types are not compatible) instead of throwing an exception as the direct cast the 'as' operator sets the reference to null.
If you only have one datatable in your dataset then you can get the first element like this:
ds.Tables[0];
... or use the name of the table:
ds.Tables["myTable"];
in your case you can try...
DataTable dt = GridView1.DataSource.Tables[0] as DataTable;
Hope it helps!
EDIT:
with regards to your sorting problem (once you get the datatable):
if (dt != null)
{
dt.DefaultView.Sort = e.SortExpression + " " + ConvertSortDirectionToSql(e.SortDirection);
GridView1.DataBind();
}
You can do this because dt is a reference to the exact same object that's already set as DataSource for your grid. It should do the trick - if not there's smt else I am missing (such as we're sorting the wrong table meaning you have more than one table in the DataSet).
EDIT:
had a look at your code. I don't know exactly when GetValues gets fired but I suspect it's causing your problem (I think it might be overriding your sorting or smt along those lines).
If you comment out FillDataSource from getValues and modify your PageLoad to do this:
void Page_Load(Object sender, EventArgs e)
{
// Load data only once, when the page is first loaded.
if (!IsPostBack)
{
Session["myDataSet"] = FillDataSet();
}
}
then in your sort method you retrieve the DataSource like this:
DataTable dt = ((DataSet)Session["myDataSet"]).Tables[0];
Also you can retrieve the DataSet from session in your pagination handler method.
You should also notice an improvement in performance since you're retrieving the stuff form the db just once.
Give it a shot!
In Testing.aspx.cs
protected void GridView1_Sorting(object sender, GridViewSortEventArgs e)
{
if (dataset != null)
{
datatable = dataset.Tables[0];
DataView dataView = new DataView(datatable);
dataView.Sort = e.SortExpression;
GridView1.DataSource = dataView;
GridView1.DataBind();
}
}
In Testing.aspx
<asp:GridView ID="GridView1" runat="server"
AllowSorting="True" OnSorting="GridView1_Sorting">

Code to create Sorting for a GridView in ASP.net in Code Behind?

This is my code code for the Page_Load Event
OdbcConnection myConnection;
DataSet dataSet = new DataSet();
OdbcDataAdapter adapter;
//making my connection
myConnection = new OdbcConnection(ConfigurationManager.ConnectionStrings ["ODBC_ConnectionString"].ConnectionString);
adapter = new OdbcDataAdapter("SELECT * from Company", myConnection);
adapter.Fill(dataSet, "MyData");
GridView1.DataSource = dataSet;
Session["DataSource"] = dataSet;
GridView1.DataBind();
This is my code for the PageIndexChanging event and it all works fine.
DataSet ds = new DataSet();
if (Session["DataSource"] != null)
ds = ((DataSet)Session["DataSource"]);
GridView1.DataSource = ds;
GridView1.PageIndex = e.NewPageIndex;
this.GridView1.DataBind();
Now what code do i need to create the Sorting event?
protected void GridView1_Sorting(object sender, GridViewSortEventArgs e)
{
?????????????????????????
}
Etienne
I usually do this:
public string SortField {
get {
return (string) ViewState["_sortField"];
}
set {
ViewState["_sortField"] = value;
}
}
public string SortDir {
get {
return (string) ViewState["_sortDir"];
}
set {
ViewState["_sortDir"] = value;
}
}
Put your code to do databinding into another Method because you have to call it during Sort, Paging, and when your page first loads. Call it DoDataBind() for example. Then you have in DoDataBind()
DataTable dt = yourDataSet.Tables[0];
dt.DefaultView.Sort = SortField + " " + SortDir;
GridView1.DataSource = dt.DefaultView;
GridView1.DataBind();
Then your event looks like this:
protected void GridView1_Sorting(object sender, GridViewSortEventArgs e) {
if (e.SortExpression == SortField && SortDir != "desc") {
SortDir = "desc";
}
else {
SortDir = "asc";
}
SortField = e.SortExpression;
DoDataBind();
}
Then in your aspx page you'll need to specify what the SortExpression is. For example something like this:
<asp:BoundField DataField="FIRSTNAME"
HeaderText="First Name" SortExpression="FIRSTNAME" />
You can filter and sort your dataset using:
ds.Tables[0].Select(filterExp, sortExp, etc...);

Categories

Resources