GridViewsorting:SortDirection始终为升序

我有一个网格视图,我需要sorting的元素,当用户点击标题。
它的数据源是一个List对象。

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

当用户点击标题时:

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

我的问题是,e.SortDirection总是设置为升序。
我有一个类似的代码的网页,它运作良好,e.SortDirection交替之间升序和降序。

我做错了什么 ?

您可以使用会话variables来存储最新的sortingexpression式,并且在下次对网格进行sorting时,将网格的sortingexpression式与存储最后一个sortingexpression式的Sessionvariables进行比较。 如果列是相同的,那么检查以前的sorting方向,并按照相反的方向sorting。

例:

 DataTable sourceTable = GridAttendence.DataSource as DataTable; DataView view = new DataView(sourceTable); string[] sortData = Session["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"; } 

Session和Viewstate的问题在于,如果页面上有多个GridView,则还必须跟踪SortColumn和Direction所存储的GridView控件。

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

这里是一个例子:

 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"); } } 

简单的解决scheme:

 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上默认的GridViewsorting和轻量级。

用法:

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

自动双向sorting只适用于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(); } 

这个问题不仅存在于SQL数据源中,而且还存在于对象数据源中。 但是,在代码中dynamic设置DataSource的时候,这是不好的。 不幸的是,MSDN有时在信息上真的很差。 一个简单的提到这种行为(这不是一个错误,而是一个devise问题)会节省很多时间。 无论如何,我不是很倾向于使用会话variables。 我通常将sorting方向存储在ViewState中。

我这样做的方式类似于接受的答案提供的代码,有点不同,所以我想我也会把它放在那里。 注意这个sorting是在DataTable被绑定到GridView .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; } 

我不知道为什么每个人都忘记使用隐藏的领域! 他们比ViewState“更便宜”(自2005年以来我已经closures了)。 如果你不想使用Session或ViewState,那么这里是我的解决scheme:

把这两个隐藏的字段放在你的aspx页面上,并把你想要的数据的默认sorting(例如我使用LastName):

 <asp:HiddenField ID="hfSortExpression" runat="server" Value="LastName" /> <asp:HiddenField ID="hfSortDirection" runat="server" Value="Ascending" /> 

然后把这个帮手代码放在你的基本页面(你有一个基本页面不是吗?如果没有,把你的.cs代码放在后面)。

 /// <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; } 

接下来,您需要处理网格sorting事件处理程序中的sorting。 在调用获取数据的主方法之前,从sorting事件处理程序调用上面的方法

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

既然有那么多的例子使用DataTables或者DataViews或者其他非LINQ友好的集合,我想我会包含一个例子调用一个返回一个通用列表的中间层方法,并且使用LINQ进行sorting以完成让这个例子更加“真实”:

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

最后,这里是在自定义对象的通用列表上使用LINQ的向下和脏sorting。 我敢肯定,那里有更奇特的东西可以做到这一点,但是这说明了这个概念:

私人静态列表sorting(stringsortExpression,SortDirection sortDirection,列出pendingCases){

  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; } 

最后但并非最不重要的(我是否已经说过了?),你可能想要在你的Page_Load处理程序中join类似的东西,这样在加载页面时,网格默认会绑定…注意,_accountId是一个查询string参数,转换为一个自定义在这种情况下,我自己的AccountIDtypes…

  if (!Page.IsPostBack) { //sort by LastName ascending by default GetCases(_accountId,hfSortExpression.Value,SortDirection.Ascending); } 

所有答案都不完全正确。 我用那个:

 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_Sorting …

这可以在不使用视图状态或会话的情况下完成。 当前订单可以根据我们sorting的列中第一行和最后一行的值确定:

  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(); } 
  <asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="false" AllowSorting="True" onsorting="GridView1_Sorting" EnableViewState="true"> <Columns><asp:BoundField DataField="bookid" HeaderText="BOOK ID" SortExpression="bookid" /> <asp:BoundField DataField="bookname" HeaderText="BOOK NAME" /> <asp:BoundField DataField="writer" HeaderText="WRITER" /> <asp:BoundField DataField="totalbook" HeaderText="TOTAL BOOK" SortExpression="totalbook" /> <asp:BoundField DataField="availablebook" HeaderText="AVAILABLE BOOK" /> //gridview code on page load under ispostback false//after that. protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) { string query = "SELECT * FROM book"; DataTable DT = new DataTable(); SqlDataAdapter DA = new SqlDataAdapter(query, sqlCon); DA.Fill(DT); GridView1.DataSource = DT; GridView1.DataBind(); } } protected void GridView1_Sorting(object sender, GridViewSortEventArgs e) { string query = "SELECT * FROM book"; DataTable DT = new DataTable(); SqlDataAdapter DA = new SqlDataAdapter(query, sqlCon); DA.Fill(DT); GridView1.DataSource = DT; GridView1.DataBind(); if (DT != null) { DataView dataView = new DataView(DT); dataView.Sort = e.SortExpression + " " + ConvertSortDirectionToSql(e.SortDirection); GridView1.DataSource = dataView; GridView1.DataBind(); } } private string GridViewSortDirection { get { return ViewState["SortDirection"] as string ?? "DESC"; } set { ViewState["SortDirection"] = value; } } private string ConvertSortDirectionToSql(SortDirection sortDirection) { switch (GridViewSortDirection) { case "ASC": GridViewSortDirection = "DESC"; break; case "DESC": GridViewSortDirection = "ASC"; break; } return GridViewSortDirection; } } 

另外一个:)不需要硬编码列名

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

ant然后:

  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; } 

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

所以….

List<V_ReportPeriodStatusEntity> items = GetPeriodStatusesForScreenSelection();
items.Sort(new Helpers.GenericComparer<V_ReportPeriodStatusEntity>(e.SortExpression, e.SortDirection));
grdHeader.SortDirection = e.SortDirection.Equals(SortDirection.Ascending) ? SortDirection.Descending : SortDirection.Ascending;
grdHeader.DataSource = items;
grdHeader.DataBind();

我厌倦了处理这个问题,把sorting方向和sorting列ViewState ….

要切换升序和降序,我在我的应用程序的BasePage中使用一个方法来cachingsortingexpression式和sorting方向:

 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的sorting方法调用SetPageSort,并绑定GridView:

 protected void gv_Sorting(object sender, GridViewSortEventArgs e) { SetPageSort(e); BindGrid(); } 

BindGrid检查SortExpression并使用它和SortDirection在网格的数据源上执行ORDERY BY,如下所示:

 if (SortExpression.Length > 0) { qry.ORDER_BY(SortExpression + " " + SortDirection); } gv.DataSource = qry.ExecuteReader(); gv.DataBind(); 

所以,基类SetPageSort删除了很多GridViewsorting的苦差事。 我觉得我忘记了一些东西,但这是一般的想法。

这可能会打赌埋在这里,但我提出的解决scheme,这对我的情况很好:

表单加载事件看起来像这样:

 private DataTable DataTable1; protected void Page_Load(object sender, EventArgs e) { DataTable1 = GetDataFromDatabase(); this.GridView1.DataSource = DataTable1.DefaultView; this.GridView1.DataBind(); } 

在页面上添加两个隐藏的字段:

 <asp:HiddenField runat="server" ID="lastSortDirection" /> <asp:HiddenField runat="server" ID="lastSortExpression" /> 

将以下内容添加到您的asp:GridView对象中:

 AllowSorting="True" OnSorting="GridView1_Sorting" 

使用以下GridViewsorting事件

 protected void GridView1_Sorting(object sender, GridViewSortEventArgs e) { if (lastSortExpression.Value == e.SortExpression.ToString()) { if (lastSortDirection.Value == SortDirection.Ascending.ToString()) { e.SortDirection = SortDirection.Descending; } else { e.SortDirection = SortDirection.Ascending; } lastSortDirection.Value = e.SortDirection.ToString(); lastSortExpression.Value = e.SortExpression; } else { lastSortExpression.Value = e.SortExpression; e.SortDirection = SortDirection.Ascending; lastSortDirection.Value = e.SortDirection.ToString(); } DataView dv = DataTable1.DefaultView; if (e.SortDirection == SortDirection.Ascending) { dv.Sort = e.SortExpression; } else { dv.Sort = e.SortExpression + " DESC"; } DataTable1 = dv.ToTable(); GridView1.DataSource = DataTable1.DefaultView; GridView1.DataBind(); } 

现在,我的GridView中的每一列都是sorting的,如果任何列发生变化,不需要进一步的更改。

XML:

 <asp:BoundField DataField="DealCRMID" HeaderText="Opportunity ID" SortExpression="DealCRMID"/> <asp:BoundField DataField="DealCustomerName" HeaderText="Customer" SortExpression="DealCustomerName"/> <asp:BoundField DataField="SLCode" HeaderText="Practice" SortExpression="SLCode"/> 

码:

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

旧的string,但也许我的答案会帮助别人。

首先把你的SqlDataSource作为一个DataView:

 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 

然后使用扩展方法进行sorting(类似cheep shot,但一个好的开始):

 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]; } } 

上面使用SecretSquirrel的解决scheme

这里是我完整的工作,生产代码。 只需将dgvCoaches更改为您的网格视图名称。

在网格的绑定过程中

  dgvCoaches.DataSource = dsCoaches.Tables[0]; ViewState["AllCoaches"] = dsCoaches.Tables[0]; dgvCoaches.DataBind(); 

现在sorting

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

这里是aspx代码:

 <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> 

我有一个可怕的问题,所以我最终诉诸使用LINQ命令DataTable之前分配给视图:

 Dim lquery = From s In listToMap Select s Order By s.ACCT_Active Descending, s.ACCT_Name 

特别是当sorting布尔型字段时,我确实发现DataView.Sort和DataGrid.Sort方法不可靠。

我希望这可以帮助那里的人。

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

也许这会帮助别人。 不知道这是因为它是2014年,或者我不明白这个post试图解决这个问题,但这是非常简单的slickgrid如下:

这个问题似乎是如何“记住”当前的sorting设置是什么,所以Asp.Net的build议是为你保留这个价值的。 但是slickGrid可以告诉你当前的sorting顺序是什么:

要切换sortingasc desc你可以使用grid.getSortColumns()来找出列的sorting当前是什么。 这是我做的,但我只在一列上sorting,因此我可以安全地做到这一点:'if(grid.getSortColumns()[0] .sortAsc)'

…所以我的代码是这样的:

  // 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 }, ]; 

..像往常一样加载你的数据,然后sorting部分:

  // 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)); } 

Lastly make sure you have the SlickGrid image folder included in your site and you'll get the asc/desc arrows appearing on the column when you select it. If they are missing the text will go italics but no arrows will appear.

Wrote this, it works for me:

  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; } 

In vb.net but very simple!

 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