代码之家  ›  专栏  ›  技术社区  ›  Julien N

网格视图排序:排序方向始终升序

  •  65
  • Julien N  · 技术社区  · 16 年前

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

    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总是设置为升序。
    我的网页有一个相似的代码,它很好地工作,即排序方向交替上升和下降。

    我做错了什么?

    24 回复  |  直到 8 年前
        1
  •  32
  •   abatishchev Karl Johan    15 年前

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

    例子:

    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";
    }
    
        2
  •  49
  •   rwo    16 年前

    会话和视图状态的问题是,如果页面上有多个GridView,则还必须跟踪存储SortColumn和方向的GridView控件。

    会话和视图状态的另一种选择是向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");
        }
    
    }
    
        3
  •  20
  •   maxbeaudoin    12 年前

    一个简单的解决方案:

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

    很像默认的网格视图排序和视图状态的轻量级。

    用途:

    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();
    }
    
        4
  •  19
  •   Sander    16 年前

    自动双向排序只适用于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();
        }
    
        5
  •  15
  •   George    16 年前

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

        6
  •  10
  •   Community CDub    8 年前

    我这样做的方式与 accepted answer 但是,有点不同,所以我想我也会把它放在那里。请注意,此排序是对 DataTable 在它被绑定到 GridView DataSource。

    选项一:使用视图状态

    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;
    }
    
        7
  •  5
  •   AdamE    10 年前

    我不知道为什么每个人都忘记使用隐藏的字段!它们比ViewState(我从2005年就关闭了)便宜得多。如果您不想使用会话或视图状态,下面是我的解决方案:

    将这两个隐藏字段放在您的ASPX页面上,并为您的数据设置默认排序(例如,我使用的是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;
    }
    

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

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

    因为有这么多的示例使用数据表、数据视图或其他不支持LINQ的集合,所以我想我应该包括一个示例,一个对返回泛型列表的中间层方法的调用,并使用LINQ进行排序,以便将示例四舍五入,使其更为“真实世界”:

    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进行的向下的脏排序。我敢肯定,有一些更高级的东西可以实现这个技巧,但这说明了这个概念:

    私有静态列表排序(String SortExpression、SortDirection SortDirection、List 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;
    }
    

    最后但并非最不重要(我已经说过了吗?)您可能希望在页面加载处理程序中放入类似的内容,以便网格在页面加载时默认绑定…注意_accountid是一个querystring参数,在本例中转换为我自己的accountid自定义类型…

        if (!Page.IsPostBack)
        {
            //sort by LastName ascending by default
            GetCases(_accountId,hfSortExpression.Value,SortDirection.Ascending);
        }
    
        8
  •  3
  •   in4man_1    14 年前

    所有的答案都不完全正确。我用的是:

    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中\排序…

        9
  •  3
  •   Arijus Gilbrantas    11 年前

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

    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;
            }
    
        10
  •  3
  •   PrzemG    11 年前

    它可以在不使用视图状态或会话的情况下完成。当前顺序可以根据排序依据列的第一行和最后一行中的值确定:

            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();
        }
    
        11
  •  2
  •   Taryn Frank Pearson    13 年前
            <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;
        }
    }
    
        12
  •  2
  •   Dave Lucre    12 年前

    这可能是埋在这里的赌注,但我提出的解决方案对我的情况很有用:

    窗体加载事件如下所示:

    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"
    

    使用以下GridView排序事件

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

    现在,我的网格视图中的每一列都会排序,如果其中任何一列发生更改,就不需要进行任何进一步的更改。

        13
  •  1
  •   Michael DeLorenzo    16 年前

    我用了一个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();

        14
  •  1
  •   DiningPhilanderer    16 年前

    我厌倦了处理这个问题,把排序方向和排序列放在视图状态中……

        15
  •  1
  •   djuth    16 年前

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

    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都是基本页中的属性,用于存储和从ViewState检索它们的值。

    所以我所有的派生页面都只是从GridView的排序方法调用setpagesort,并绑定GridView:

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

    binggrid检查sortExpression并使用它和sortDirection在网格的数据源上执行ordery by,如下所示:

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

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

        16
  •  1
  •   erlando    12 年前

    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();
        }
    }
    
        17
  •  1
  •   Ali    12 年前

    这是解决问题的另一种方法:

    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();
    }
    
        18
  •  1
  •   mcfea    11 年前

    旧的字符串,但也许我的答案会帮助某人。

    首先获取作为数据视图的sqldatasource:

    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];
        }
    }
    
        19
  •  1
  •   Community CDub    8 年前

    使用小松鼠的 solution above

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

    …在网格绑定期间

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

    这是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>
    
        20
  •  0
  •   abatishchev Karl Johan    13 年前

    我对此有一个可怕的问题,所以在将数据表分配给视图之前,我最终使用LINQ对其进行排序:

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

    特别是,我发现在对布尔字段进行排序时,dataview.sort和datagrid.sort方法不可靠。

    我希望这能帮助别人。

        21
  •  0
  •   Mario S    12 年前
    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();
    }
    
        22
  •  0
  •   Barry McDermid    11 年前

    也许这会对某人有所帮助。不确定是因为2014年,还是我不理解这篇文章试图解决的问题,但这对于slickgrid来说非常简单,如下所示:

    问题似乎是如何“记住”当前的排序设置是什么,所以建议是围绕着ASP.NET为您保留该值。但是slickgrid可以告诉您当前的排序顺序是:

    要切换排序asc desc,可以使用grid.getSortColumns()来确定当前的列排序。这是我所做的,但我一次只能对1列进行排序,因此我可以安全地执行此操作:“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 }, ];
    

    …像往常一样加载数据,然后加载排序部分:

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

    最后,确保您的站点中包含slickgrid image文件夹,并且当您选择它时,您将在列上显示asc/desc箭头。如果它们丢失,文本将变为斜体,但不会出现箭头。

        23
  •  0
  •   Rasmus W    8 年前

    写下这个,它对我有用:

     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;
        }
    
        24
  •  -1
  •   Roman Marusyk S Kotra    8 年前

    在vb.net中,但非常简单!

    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
    
    推荐文章