Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Asp.net GridView排序:排序方向始终为升序_Asp.net_Sorting_Gridview - Fatal编程技术网

Asp.net GridView排序:排序方向始终为升序

Asp.net GridView排序:排序方向始终为升序,asp.net,sorting,gridview,Asp.net,Sorting,Gridview,我有一个gridview,当用户单击标题时,我需要对其元素进行排序。 它的数据源是一个列表对象 aspx的定义如下: <asp:GridView ID="grdHeader" AllowSorting="true" AllowPaging="false" AutoGenerateColumns="false" Width="780" runat="server" OnSorting="grdHeader_OnSorting" EnableViewState="true">

我有一个gridview,当用户单击标题时,我需要对其元素进行排序。
它的数据源是一个列表对象

aspx的定义如下:

<asp:GridView ID="grdHeader" AllowSorting="true" AllowPaging="false" 
    AutoGenerateColumns="false" Width="780" runat="server"  OnSorting="grdHeader_OnSorting" EnableViewState="true">
    <Columns>
        <asp:BoundField DataField="Entitycode" HeaderText="Entity" SortExpression="Entitycode" />
        <asp:BoundField DataField="Statusname" HeaderText="Status" SortExpression="Statusname" />
        <asp:BoundField DataField="Username" HeaderText="User" SortExpression="Username" />
    </Columns>
</asp:GridView>

代码隐藏是这样定义的:
首次加载:

protected void btnSearch_Click(object sender, EventArgs e)
{
    List<V_ReportPeriodStatusEntity> items = GetPeriodStatusesForScreenSelection();
    this.grdHeader.DataSource = items;
    this.grdHeader.DataBind();
}
protectedvoidbtnsearch\u单击(对象发送方,事件参数e)
{
列表项=GetPeriodStatusesForScreenSelection();
this.grdHeader.DataSource=项目;
this.grdHeader.DataBind();
}
当用户单击标题时:

protected void grdHeader_OnSorting(object sender, GridViewSortEventArgs e)
{
    List<V_ReportPeriodStatusEntity> items = GetPeriodStatusesForScreenSelection();
    items.Sort(new Helpers.GenericComparer<V_ReportPeriodStatusEntity>(e.SortExpression, e.SortDirection));
    grdHeader.DataSource = items;
    grdHeader.DataBind();
}
protectedvoid grdHeader\u OnSorting(对象发送方,GridViewSortEventArgs e)
{
列表项=GetPeriodStatusesForScreenSelection();
条目.Sort(新助手.GenericComparer(e.SortExpression,e.SortDirection));
grdHeader.DataSource=项目;
grdHeader.DataBind();
}
我的问题是e.SortDirection总是设置为升序。
我有一个类似代码的网页,它工作得很好,例如SortDirection在升序和降序之间交替


我做错了什么?

我已经有一段时间没有使用GridView了,但我认为在离开OnSorting方法之前,需要将网格的SortDirection属性设置为当前的任何属性

所以

List items=GetPeriodStatusesForScreenSelection()
items.Sort(新的Helpers.GenericComparer(e.SortExpression,e.SortDirection))
grdHeader.SortDirection=e.SortDirection.Equals(SortDirection.升序)?下降方向:上升方向
grdHeader.DataSource=项目

grdHeader.DataBind()

我厌倦了处理这个问题,并将排序方向和排序列放在ViewState中……

要切换升序和降序,我在应用程序的基本页中使用一种方法来缓存排序表达式和排序方向:

protected void SetPageSort(GridViewSortEventArgs e)
{
    if (e.SortExpression == SortExpression)
    {
        if (SortDirection == "ASC")
        {
            SortDirection = "DESC";
        }
        else
        {
            SortDirection = "ASC";
        }
    }
    else
    {
        SortDirection = "ASC";
        SortExpression = e.SortExpression;
    }
}
SortExpression和SortDirection都是BasePage中的属性,用于从ViewState存储和检索它们的值

因此,我的所有派生页面只需从GridView的排序方法调用SetPageSort,并绑定GridView:

protected void gv_Sorting(object sender, GridViewSortEventArgs e)
{
    SetPageSort(e);
    BindGrid();
}
BindGrid检查SortExpression,并使用它和SortDirection对网格的数据源执行排序,如下所示:

if (SortExpression.Length > 0)
{
    qry.ORDER_BY(SortExpression + " " + SortDirection);
}

gv.DataSource = qry.ExecuteReader();
gv.DataBind();
private DataTable DataTable1;
protected void Page_Load(object sender, EventArgs e)
{
  DataTable1 = GetDataFromDatabase();
  this.GridView1.DataSource = DataTable1.DefaultView;
  this.GridView1.DataBind();
}
    // Make sure you have sortable: true on the relevant column names or 
    // nothing happens as I found!!
    var columns = [
    { name: "FileName", id: "FileName", field: "FileName", width: 95, selectable: true, sortable: true },
    { name: "Type", id: "DocumentType", field: "DocumentType", minWidth: 105, width: 120, maxWidth: 120, selectable: true, sortable: true },
    { name: "ScanDate", id: "ScanDate", field: "ScanDate", width: 90, selectable: true, sortable: true }, ];
            // Created Date
            if (sortBy == "CreatedDate")
            {
                if (SortByDirection == SortDirection.Ascending)
                {
                    data = data.OrderBy(x => x.CreatedDate).ToList();
                    SortByDirection = SortDirection.Descending;
                }
                else {
                    data = data.OrderByDescending(x => x.CreatedDate).ToList();
                    SortByDirection = SortDirection.Ascending;
                } 
            }

因此,基类的SetPageSort消除了GridView排序的许多繁琐工作。我感觉好像忘记了什么,但这是一般的想法。

自动双向排序只适用于SQL数据源。不幸的是,MSDN中的所有文档都假设您正在使用它,因此GridView可能会有点令人沮丧

我做这件事的方法是自己跟踪订单。例如:

    protected void OnSortingResults(object sender, GridViewSortEventArgs e)
    {
        // If we're toggling sort on the same column, we simply toggle the direction. Otherwise, ASC it is.
        // e.SortDirection is useless and unreliable (only works with SQL data source).
        if (_sortBy == e.SortExpression)
            _sortDirection = _sortDirection == SortDirection.Descending ? SortDirection.Ascending : SortDirection.Descending;
        else
            _sortDirection = SortDirection.Ascending;

        _sortBy = e.SortExpression;

        BindResults();
    }
<asp:HiddenField ID="hfSortExpression" runat="server" Value="LastName" />
<asp:HiddenField ID="hfSortDirection" runat="server" Value="Ascending" />

您可以使用会话变量存储最新的排序表达式,并在下次对网格进行排序时,将网格的排序表达式与存储最后一个排序表达式的会话变量进行比较。如果列相等,则检查上一次排序的方向和反向排序

示例:

DataTable sourceTable = GridAttendence.DataSource as DataTable;
DataView view = new DataView(sourceTable);
string[] sortData = ViewState["sortExpression"].ToString().Trim().Split(' ');
if (e.SortExpression == sortData[0])
{
    if (sortData[1] == "ASC")
    {
        view.Sort = e.SortExpression + " " + "DESC";
        this.ViewState["sortExpression"] = e.SortExpression + " " + "DESC";
    }
    else
    {
        view.Sort = e.SortExpression + " " + "ASC";
        this.ViewState["sortExpression"] = e.SortExpression + " " + "ASC";
    }
}
else
{
    view.Sort = e.SortExpression + " " + "ASC";
    this.ViewState["sortExpression"] = e.SortExpression + " " + "ASC";
}
protected void grdHeader_OnSorting(object sender, GridViewSortEventArgs e)
{
    List<V_ReportPeriodStatusEntity> items = GetPeriodStatusesForScreenSelection();

    items.Sort(new Helpers.GenericComparer<V_ReportPeriodStatusEntity>(e.SortExpression, GetSortDirection(e.SortExpression));
    grdHeader.DataSource = items;
    grdHeader.DataBind();
}

这个问题不仅在SQL数据源中没有,在对象数据源中也没有。但是,当在代码中动态设置数据源时,情况就变糟了。不幸的是,MSDN有时在信息方面真的很差。只要简单地提到这个行为(这不是一个bug,而是一个设计问题),就会节省很多时间。无论如何,我不太倾向于使用会话变量。我通常将排序方向存储在ViewState中。

我这样做的方式与提供的代码类似,但位有点不同,因此我认为我也应该将其放在那里。请注意,此排序是在绑定到.DataSource之前对进行的

选项一:使用ViewState

void DataGrid_Sorting(object sender, GridViewSortEventArgs e)
{
    if (e.SortExpression == (string)ViewState["SortColumn"])
    {
        // We are resorting the same column, so flip the sort direction
        e.SortDirection = 
            ((SortDirection)ViewState["SortColumnDirection"] == SortDirection.Ascending) ? 
            SortDirection.Descending : SortDirection.Ascending;
    }
    // Apply the sort
    this._data.DefaultView.Sort = e.SortExpression +
        (string)((e.SortDirection == SortDirection.Ascending) ? " ASC" : " DESC");
    ViewState["SortColumn"] = e.SortExpression;
    ViewState["SortColumnDirection"] = e.SortDirection;
}
选项二:使用会话

请注意,如果您在该字段中看到以下内容,或者您仍然支持针对较旧浏览器的公司系统,则提供以下内容是出于遗留目的

void DataGrid_Sorting(object sender, GridViewSortEventArgs e)
{
    if (e.SortExpression == (string)HttpContext.Current.Session["SortColumn"])
    {
        // We are resorting the same column, so flip the sort direction
        e.SortDirection = 
            ((SortDirection)HttpContext.Current.Session["SortColumnDirection"] == SortDirection.Ascending) ? 
            SortDirection.Descending : SortDirection.Ascending;
    }
    // Apply the sort
    this._data.DefaultView.Sort = e.SortExpression +
        (string)((e.SortDirection == SortDirection.Ascending) ? " ASC" : " DESC");
    HttpContext.Current.Session["SortColumn"] = e.SortExpression;
    HttpContext.Current.Session["SortColumnDirection"] = e.SortDirection;
}
一个简单的解决方案:

protected SortDirection GetSortDirection(string column)
{
    SortDirection nextDir = SortDirection.Ascending; // Default next sort expression behaviour.
    if (ViewState["sort"] != null && ViewState["sort"].ToString() == column)
    {   // Exists... DESC.
        nextDir = SortDirection.Descending;
        ViewState["sort"] = null;
    }
    else
    {   // Doesn't exists, set ViewState.
        ViewState["sort"] = column;
    }
    return nextDir;
}
与ViewState上的默认GridView排序和轻量级非常相似

用法:

DataTable sourceTable = GridAttendence.DataSource as DataTable;
DataView view = new DataView(sourceTable);
string[] sortData = ViewState["sortExpression"].ToString().Trim().Split(' ');
if (e.SortExpression == sortData[0])
{
    if (sortData[1] == "ASC")
    {
        view.Sort = e.SortExpression + " " + "DESC";
        this.ViewState["sortExpression"] = e.SortExpression + " " + "DESC";
    }
    else
    {
        view.Sort = e.SortExpression + " " + "ASC";
        this.ViewState["sortExpression"] = e.SortExpression + " " + "ASC";
    }
}
else
{
    view.Sort = e.SortExpression + " " + "ASC";
    this.ViewState["sortExpression"] = e.SortExpression + " " + "ASC";
}
protected void grdHeader_OnSorting(object sender, GridViewSortEventArgs e)
{
    List<V_ReportPeriodStatusEntity> items = GetPeriodStatusesForScreenSelection();

    items.Sort(new Helpers.GenericComparer<V_ReportPeriodStatusEntity>(e.SortExpression, GetSortDirection(e.SortExpression));
    grdHeader.DataSource = items;
    grdHeader.DataBind();
}
protectedvoid grdHeader\u OnSorting(对象发送方,GridViewSortEventArgs e)
{
列表项=GetPeriodStatusesForScreenSelection();
条目.Sort(新助手.GenericComparer(e.SortExpression,GetSortDirection(e.SortExpression));
grdHeader.DataSource=项目;
grdHeader.DataBind();
}

会话和视图状态的问题是,如果页面上有多个gridview,您还必须跟踪存储SortColumn和Direction的gridview控件

Session和Viewstate的替代方法是向Gridview添加2个属性,并以这种方式跟踪列和方向

以下是一个例子:

private void GridViewSortDirection(GridView g, GridViewSortEventArgs e, out SortDirection d, out string f)
{
    f = e.SortExpression;
    d = e.SortDirection;

    //Check if GridView control has required Attributes
    if (g.Attributes["CurrentSortField"] != null && g.Attributes["CurrentSortDir"] != null)
    {
        if (f == g.Attributes["CurrentSortField"])
        {
            d = SortDirection.Descending;
            if (g.Attributes["CurrentSortDir"] == "ASC")
            {
                d = SortDirection.Ascending;
            }
        }

        g.Attributes["CurrentSortField"] = f;
        g.Attributes["CurrentSortDir"] = (d == SortDirection.Ascending ? "DESC" : "ASC");
    }

}

我遇到了一个可怕的问题,所以在将数据表分配给视图之前,我最终求助于使用LINQ对数据表进行排序:

Dim lquery = From s In listToMap
             Select s
             Order By s.ACCT_Active Descending, s.ACCT_Name
特别是,我发现在对布尔字段进行排序时,DataView.Sort和DataGrid.Sort方法是不可靠的


我希望这有助于其他人。

所有这些答案都不完全正确。我使用:

protected void SetPageSort(GridViewSortEventArgs e) 
        { 
            if (e.SortExpression == SortExpression) 
            { 
                if (SortDirection == "ASC") 
                { 
                    SortDirection = "DESC"; 
                } 
                else 
                { 
                    SortDirection = "ASC"; 
                } 
            } 
            else 
            {
                if (SortDirection == "ASC")
                {
                    SortDirection = "DESC";
                }
                else
                {
                    SortDirection = "ASC";
                } 
                SortExpression = e.SortExpression; 
            } 
        } 
  protected void gridView_Sorting(object sender, GridViewSortEventArgs e)
        {
            SetPageSort(e); 
在gridView\u排序中…

void dg\u SortCommand(对象源,DataGridSortCommand)
void dg_SortCommand(object source, DataGridSortCommandEventArgs e)
{
    DataGrid dg = (DataGrid) source;
    string sortField = dg.Attributes["sortField"];
    List < SubreportSummary > data = (List < SubreportSummary > ) dg.DataSource;
    string field = e.SortExpression.Split(' ')[0];
    string sort = "ASC";
    if (sortField != null)
    {
        sort = sortField.Split(' ')[0] == field ? (sortField.Split(' ')[1] == "DESC" ? "ASC" : "DESC") : "ASC";
    }
    dg.Attributes["sortField"] = field + " " + sort;
    data.Sort(new GenericComparer < SubreportSummary > (field, sort, null));
    dg.DataSource = data;
    dg.DataBind();
}
{ DataGrid dg=(DataGrid)源; 字符串sortField=dg.Attributes[“sortField”]; Listdata=(List)dg.DataSource; 字符串字段=e.SortExpression.Split(“”)[0]; 字符串sort=“ASC”; if(sortField!=null) { sort=sortField.Split(“”)[0]==field?(sortField.Split(“”)[1]==“说明”?“ASC”:“说明”):“ASC”; } dg.Attributes[“sortField”]=字段+“”+排序; 排序(新的GenericComparer(字段,排序,null)); dg.DataSource=数据; dg.DataBind(); }

private string ConvertSortDirectionToSql(String sortExpression,SortDirection sortDireciton)
{
    switch (sortExpression)
    {
        case "DealCRMID":
             ViewState["DealCRMID"]=ChangeSortDirection(ViewState["DealCRMID"].ToString());
             return ViewState["DealCRMID"].ToString();

        case "DealCustomerName":
             ViewState["DealCustomerName"] = ChangeSortDirection(ViewState["DealCustomerName"].ToString());
             return ViewState["DealCustomerName"].ToString();

        case "SLCode":
             ViewState["SLCode"] = ChangeSortDirection(ViewState["SLCode"].ToString());
             return ViewState["SLCode"].ToString();

        default:
            return "ASC";
    }       
}

private string ChangeSortDirection(string sortDireciton)
{
    switch (sortDireciton)
    {
        case "DESC":
            return "ASC";
        case "ASC":
            return "DESC";
        default:
            return "ASC";
    }
}

protected void gvPendingApprovals_Sorting(object sender, GridViewSortEventArgs e)
{
    DataSet ds = (System.Data.DataSet)(gvPendingApprovals.DataSource);

    if(ds.Tables.Count>0)
    {
        DataView m_DataView = new DataView(ds.Tables[0]);
        m_DataView.Sort = e.SortExpression + " " + ConvertSortDirectionToSql   (e.SortExpression.ToString(), e.SortDirection);

        gvPendingApprovals.DataSource = m_DataView;
        gvPendingApprovals.DataBind();
    }
}
protected void grdHeader_OnSorting(object sender, GridViewSortEventArgs e)
{
    List<V_ReportPeriodStatusEntity> items = GetPeriodStatusesForScreenSelection();
    items.Sort = e.SortExpression + " " + ConvertSortDirectionToSql(e);
    grdHeader.DataSource = items;
    grdHeader.DataBind();
}

private string ConvertSortDirectionToSql(GridViewSortEventArgs e)
{
    ViewState[e.SortExpression] = ViewState[e.SortExpression] ?? "ASC";
    ViewState[e.SortExpression] = (ViewState[e.SortExpression].ToString() == "ASC") ? "DESC" : "ASC";
    return ViewState[e.SortExpression].ToString();
}
DataTable dt = GetData();

    SortDirection sd;
    string f;
    GridViewSortDirection(gvProductBreakdown, e, out sd, out f);
    dt.DefaultView.Sort = sd == SortDirection.Ascending ? f + " asc" : f + " desc";
    gvProductBreakdown.DataSource = dt;
    gvProductBreakdown.DataBind();
 private void GridViewSortDirection(GridView g, GridViewSortEventArgs e, out SortDirection d, out string f)
    {
        f = e.SortExpression;
        d = e.SortDirection;
 if (g.Attributes[f] != null)
        {
            d = g.Attributes[f] == "ASC" ? SortDirection.Descending : SortDirection.Ascending;

            g.Attributes[f] = d == SortDirection.Ascending ? "ASC" : "DESC";
        }
        else
        {
            g.Attributes[f] = "ASC";
            d = SortDirection.Ascending;
        }
        protected void gvItems_Sorting(object sender, GridViewSortEventArgs e)
    {
        GridView grid = sender as GridView; // get reference to grid
        SortDirection currentSortDirection = SortDirection.Ascending; // default order

        // get column index by SortExpression
        int columnIndex = grid.Columns.IndexOf(grid.Columns.OfType<DataControlField>()
                                      .First(x => x.SortExpression == e.SortExpression));

        // sort only if grid has more than 1 row
        if (grid.Rows.Count > 1)
        {
            // get cells
            TableCell firstCell = grid.Rows[0].Cells[columnIndex];
            TableCell lastCell = grid.Rows[grid.Rows.Count - 1].Cells[columnIndex];

            // if field type of the cell is 'TemplateField' Text property is always empty.
            // Below assumes that value is binded to Label control in 'TemplateField'.
            string firstCellValue = firstCell.Controls.Count == 0 ? firstCell.Text : ((Label)firstCell.Controls[1]).Text;
            string lastCellValue = lastCell.Controls.Count == 0 ? lastCell.Text : ((Label)lastCell.Controls[1]).Text;

            DateTime tmpDate;
            decimal tmpDecimal;

            // try to determinate cell type to ensure correct ordering
            // by date or number
            if (DateTime.TryParse(firstCellValue, out tmpDate)) // sort as DateTime
            {
                currentSortDirection = 
                    DateTime.Compare(Convert.ToDateTime(firstCellValue), 
                                     Convert.ToDateTime(lastCellValue)) < 0 ? 
                                            SortDirection.Ascending : SortDirection.Descending;
            }
            else if (Decimal.TryParse(firstCellValue, out tmpDecimal)) // sort as any numeric type
            {
                currentSortDirection = Decimal.Compare(Convert.ToDecimal(firstCellValue), 
                                                       Convert.ToDecimal(lastCellValue)) < 0 ? 
                                                       SortDirection.Ascending : SortDirection.Descending;
            }
            else // sort as string
            {
                currentSortDirection = string.CompareOrdinal(firstCellValue, lastCellValue) < 0 ? 
                                                             SortDirection.Ascending : SortDirection.Descending;
            }
        }

        // then bind GridView using correct sorting direction (in this example I use Linq)
        if (currentSortDirection == SortDirection.Descending)
        {
            grid.DataSource = myItems.OrderBy(x => x.GetType().GetProperty(e.SortExpression).GetValue(x, null));
        }
        else
        {
            grid.DataSource = myItems.OrderByDescending(x => x.GetType().GetProperty(e.SortExpression).GetValue(x, null));
        }

        grid.DataBind();
    }
Private Sub DataGrid1_SortCommand(ByVal source As Object, ByVal e As DataGridSortCommandEventArgs) Handles grid1.SortCommand
    Dim dataView As DataView = CType(SqlDataSource1.Select(DataSourceSelectArguments.Empty), DataView)
    dataView.Sort = e.SortExpression + dataView.FieldSortDirection(Session, e.SortExpression)

    grid1.DataSourceID = Nothing
    grid1.DataSource = dataView
    grid1.DataBind()

End Sub
public static class DataViewExtensions
{
    public static string FieldSortDirection(this DataView dataView, HttpSessionState session, string sortExpression)
    {
        const string SORT_DIRECTION = "SortDirection";
        var identifier = SORT_DIRECTION + sortExpression;

        if (session[identifier] != null)
        {
            if ((string) session[identifier] == " ASC")
                session[identifier] = " DESC";
            else if ((string) session[identifier] == " DESC")
                session[identifier] = " ASC";
        }
        else
            session[identifier] = " ASC";

        return (string) session[identifier];
    }
}
    // Make sure you have sortable: true on the relevant column names or 
    // nothing happens as I found!!
    var columns = [
    { name: "FileName", id: "FileName", field: "FileName", width: 95, selectable: true, sortable: true },
    { name: "Type", id: "DocumentType", field: "DocumentType", minWidth: 105, width: 120, maxWidth: 120, selectable: true, sortable: true },
    { name: "ScanDate", id: "ScanDate", field: "ScanDate", width: 90, selectable: true, sortable: true }, ];
   // Clicking on a column header fires this event. Here we toggle the sort direction
    grid.onHeaderClick.subscribe(function(e, args) {
        var columnID = args.column.id;

        if (grid.getSortColumns()[0].sortAsc) {
            grid.setSortColumn(args.column.id, true);
        }
        else {
            grid.setSortColumn(args.column.id, false);
        }
    });

    // The actual sort function is like this 
        grid.onSort.subscribe(function (e, args) {
            sortdir = args.sortAsc ? 1 : -1;
            sortcol = args.sortCol.field;

            //alert('in sort');

            // using native sort with comparer
            // preferred method but can be very slow in IE with huge datasets
            dataView.sort(comparer, args.sortAsc);
            grid.invalidateAllRows();
            grid.render();
        });

// Default comparer is enough for what I'm doing here ..
function comparer(a, b) {
    var x = a[sortcol], y = b[sortcol];
    return (x == y ? 0 : (x > y ? 1 : -1));
}
<asp:HiddenField ID="hfSortExpression" runat="server" Value="LastName" />
<asp:HiddenField ID="hfSortDirection" runat="server" Value="Ascending" />
/// <summary>
/// Since native ASP.Net GridViews do not provide accurate SortDirections, 
/// we must save a hidden field with previous sort Direction and Expression.
/// Put these two hidden fields on page and call this method in grid sorting event
/// </summary>
/// <param name="hfSortExpression">The hidden field on page that has the PREVIOUS column that is sorted on</param>
/// <param name="hfSortDirection">The hidden field on page that has the PREVIOUS sort direction</param>
protected SortDirection GetSortDirection(GridViewSortEventArgs e, HiddenField hfSortExpression, HiddenField hfSortDirection)
{
    //assume Ascending always by default!!
    SortDirection sortDirection = SortDirection.Ascending;

    //see what previous column (if any) was sorted on
    string previousSortExpression = hfSortExpression.Value;
    //see what previous sort direction was used
    SortDirection previousSortDirection = !string.IsNullOrEmpty(hfSortDirection.Value) ? ((SortDirection)Enum.Parse(typeof(SortDirection), hfSortDirection.Value)) : SortDirection.Ascending;

    //check if we are now sorting on same column
    if (e.SortExpression == previousSortExpression)
    {
        //check if previous direction was ascending
        if (previousSortDirection == SortDirection.Ascending)
        {
            //since column name matches but direction doesn't, 
            sortDirection = SortDirection.Descending;
        }
    }

    // save them back so you know for next time
    hfSortExpression.Value = e.SortExpression;
    hfSortDirection.Value = sortDirection.ToString();

    return sortDirection;
}
protected void gridContacts_Sorting(object sender, GridViewSortEventArgs e)
{
    //get the sort direction (since GridView sortDirection is not implemented!)
    SortDirection sortDirection = GetSortDirection(e, hfSortExpression, hfSortDirection);

    //get data, sort and rebind (obviously, this is my own method... you must replace with your own)
    GetCases(_accountId, e.SortExpression, sortDirection);
}
private void GetCases(AccountID accountId, string sortExpression, SortDirection sortDirection)
{
    //get some data from a middle tier method (database etc._)(
    List<PendingCase> pendingCases = MyMiddleTier.GetCasesPending(accountId.Value);
    //show a count to the users on page (this is just nice to have)
    lblCountPendingCases.Text = pendingCases.Count.ToString();
    //do the actual sorting of your generic list of custom objects
    pendingCases = Sort(sortExpression, sortDirection, pendingCases);
    //bind your grid
    grid.DataSource = pendingCases;
    grid.DataBind();
}
    switch (sortExpression)
    {
        case "FirstName":
            pendingCases = sortDirection == SortDirection.Ascending ? pendingCases.OrderBy(c => c.FirstName).ToList() : pendingCases.OrderByDescending(c => c.FirstName).ToList();
            break;
        case "LastName":
            pendingCases = sortDirection == SortDirection.Ascending ? pendingCases.OrderBy(c => c.LastName).ToList() : pendingCases.OrderByDescending(c => c.LastName).ToList();
            break;
        case "Title":
            pendingCases = sortDirection == SortDirection.Ascending ? pendingCases.OrderBy(c => c.Title).ToList() : pendingCases.OrderByDescending(c => c.Title).ToList();
            break;
        case "AccountName":
            pendingCases = sortDirection == SortDirection.Ascending ? pendingCases.OrderBy(c => c.AccountName).ToList() : pendingCases.OrderByDescending(c => c.AccountName).ToList();
            break;
        case "CreatedByEmail":
            pendingCases = sortDirection == SortDirection.Ascending ? pendingCases.OrderBy(c => c.CreatedByEmail).ToList() : pendingCases.OrderByDescending(c => c.CreatedByEmail).ToList();
            break;
        default:
            break;
    }
    return pendingCases;
}
    if (!Page.IsPostBack)
    {
        //sort by LastName ascending by default
        GetCases(_accountId,hfSortExpression.Value,SortDirection.Ascending);
    }
        dgvCoaches.DataSource = dsCoaches.Tables[0];
        ViewState["AllCoaches"] = dsCoaches.Tables[0];
        dgvCoaches.DataBind();
protected void gridView_Sorting(object sender, GridViewSortEventArgs e)
{
    DataTable dt = ViewState["AllCoaches"] as DataTable;

    if (dt != null)
    {
        if (e.SortExpression == (string)ViewState["SortColumn"])
        {
            // We are resorting the same column, so flip the sort direction
            e.SortDirection =
                ((SortDirection)ViewState["SortColumnDirection"] == SortDirection.Ascending) ?
                SortDirection.Descending : SortDirection.Ascending;
        }
        // Apply the sort
        dt.DefaultView.Sort = e.SortExpression +
            (string)((e.SortDirection == SortDirection.Ascending) ? " ASC" : " DESC");
        ViewState["SortColumn"] = e.SortExpression;
        ViewState["SortColumnDirection"] = e.SortDirection; 

        dgvCoaches.DataSource = dt;
        dgvCoaches.DataBind();
    }
}
<asp:GridView ID="dgvCoaches" runat="server" 
    CssClass="table table-hover table-striped" GridLines="None"  DataKeyNames="HealthCoachID" OnRowCommand="dgvCoaches_RowCommand"
    AutoGenerateColumns="False" OnSorting="gridView_Sorting" AllowSorting="true">
    <Columns>
        <asp:BoundField DataField="HealthCoachID" Visible="false" />
        <asp:BoundField DataField="LastName" HeaderText="Last Name" SortExpression="LastName" />
        <asp:BoundField DataField="FirstName" HeaderText="First Name" SortExpression="FirstName" />
        <asp:BoundField DataField="LoginName" HeaderText="Login Name" SortExpression="LoginName" />
        <asp:BoundField DataField="Email" HeaderText="Email" SortExpression="Email" HtmlEncode="false" DataFormatString="<a href=mailto:{0}>{0}</a>" />
        <asp:TemplateField>
            <ItemTemplate>
                    <asp:LinkButton runat="server" BorderStyle="None" CssClass="btn btn-default" Text="<i class='glyphicon glyphicon-edit'></i>" CommandName="Update" CommandArgument="<%# ((GridViewRow) Container).RowIndex %>" />
            </ItemTemplate>
        </asp:TemplateField>
        <asp:TemplateField>
            <ItemTemplate>
                <asp:LinkButton runat="server" OnClientClick="return ConfirmOnDelete();" BorderStyle="None" CssClass="btn btn-default" Text="<i class='glyphicon glyphicon-remove'></i>" CommandName="Delete" CommandArgument="<%# ((GridViewRow) Container).RowIndex %>" />
            </ItemTemplate>
        </asp:TemplateField>
    </Columns>
    <RowStyle CssClass="cursor-pointer" />
</asp:GridView>
Protected Sub grTicketHistory_Sorting(sender As Object, e As GridViewSortEventArgs) Handles grTicketHistory.Sorting

    Dim dt As DataTable = Session("historytable")
    If Session("SortDirection" & e.SortExpression) = "ASC" Then
        Session("SortDirection" & e.SortExpression) = "DESC"
    Else
        Session("SortDirection" & e.SortExpression) = "ASC"
    End If
    dt.DefaultView.Sort = e.SortExpression & " " & Session("SortDirection" & e.SortExpression)
    grTicketHistory.DataSource = dt
    grTicketHistory.DataBind()

End Sub
 protected void GridView1_Sorting(object sender, GridViewSortEventArgs e)
    {
        if (ViewState["sortExpression"] == null || ViewState["sortExpression"].ToString() != e.SortExpression.ToString())
            MyDataTable.DefaultView.Sort = e.SortExpression + " ASC";
        else
        {
            if (ViewState["SortDirection"].ToString() == "Ascending")
                MyDataTable.DefaultView.Sort = e.SortExpression = e.SortExpression + " DESC";
            else
                MyDataTable.DefaultView.Sort = e.SortExpression + " ASC";
        }

        GridView1.DataSource = MyDataTable;
        GridView1.DataBind();

        ViewState["sortExpression"] = e.SortExpression;
        ViewState["SortDirection"] = e.SortDirection;
    }
    // ==================================================
    // SortByDirection
    // ==================================================
    public SortDirection SortByDirection
    {
        get
        {
            if (ViewState["SortByDirection"] == null)
            {
                ViewState["SortByDirection"] = SortDirection.Ascending;
            }

            return (SortDirection)Enum.Parse(typeof(SortDirection), ViewState["SortByDirection"].ToString());
        }
        set { ViewState["SortByDirection"] = value; }
    }
            // Created Date
            if (sortBy == "CreatedDate")
            {
                if (SortByDirection == SortDirection.Ascending)
                {
                    data = data.OrderBy(x => x.CreatedDate).ToList();
                    SortByDirection = SortDirection.Descending;
                }
                else {
                    data = data.OrderByDescending(x => x.CreatedDate).ToList();
                    SortByDirection = SortDirection.Ascending;
                } 
            }
protected void gv_Sorting(object sender, GridViewSortEventArgs e)
{
    DataTable dataTable = (DataTable)Cache["GridData"];

    if (dataTable != null)
    {
        DataView dataView = new DataView(dataTable);
        string Field1 = e.SortExpression;
        string whichWay = "ASC";
        if (HttpContext.Current.Session[Field1] != null)
        {
            whichWay = HttpContext.Current.Session[Field1].ToString();
            if (whichWay == "ASC")
                whichWay = "DESC";
            else
                whichWay = "ASC";               
        }

        HttpContext.Current.Session[Field1] = whichWay;
        dataView.Sort = Field1 + " " + whichWay;      
        gv.DataSource = dataView;
        gv.DataBind();
    }
}
    string SqlConn = ConfigurationManager.ConnectionStrings["Sql28"].ConnectionString;
    SqlConnection sqlcon = new SqlConnection(SqlConn);
    sqlcon.Open();

    SqlCommand cmd = new SqlCommand();
    cmd.Connection = sqlcon;
    cmd.CommandType = System.Data.CommandType.Text;
    cmd.CommandText = HttpContext.Current.Session["sql"].ToString();

    SqlDataAdapter adapter = new SqlDataAdapter(cmd);
    DataTable employees = new DataTable();
    adapter.Fill(employees);

    gv.DataSource = employees;
    gv.DataBind();

    Cache.Insert("GridData", employees, null, System.Web.Caching.Cache.NoAbsoluteExpiration,new TimeSpan(0, 360000, 0));