2

嗨,我想在 gridview 中对多列进行排序,如此处所示 .net GridView 的分层(多列)排序?

我做了我的家庭作业我的 aspx 看起来像

<%@ Page Language="C#" AutoEventWireup="True" CodeBehind="Default.aspx.cs" Inherits="_Default" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head id="Head1" runat="server">
    <title>Multiple sorting with Gridview</title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="True" 
            AllowSorting="true" onsorting="GridView1_Sorting" style="margin-right: 541px" 
            Width="873px">
        </asp:GridView>
        <p><asp:Label runat="server" ID="lblSortExpression" /></p>
    </div>
    </form>

</body>
</html>

在我的 Aspx.cs 页面中

using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.Collections.Specialized;
using System.Text;
using System.Web.UI.WebControls;
using System.Data.SqlClient;

partial class _Default : System.Web.UI.Page
{

    private ListDictionary m_ldSortExpression;
    private ListDictionary SortExpressions
    {
        get
        {
            m_ldSortExpression = (ListDictionary)ViewState["SortExpressions"];
            if (m_ldSortExpression == null)
            {
                m_ldSortExpression = new ListDictionary();
            }
            return m_ldSortExpression;
        }
        set { ViewState["SortExpressions"] = value; }
    }

    protected void Page_Load(object sender, System.EventArgs e)
    {
        if (!IsPostBack)
        {
            BindData();
        }
    }

    public void BindData()
    {
        // Usually you would get the data from the database.
        // To simplify the code, I will just fill a datatable with some standard data.
        DataTable dt = new DataTable();
        dt.Columns.Add("FirstName");
        dt.Columns.Add("LastName");
        dt.Columns.Add("Age");
        dt.Columns.Add("Position");

        dt.Rows.Add(new object[] {
            "1",
            "2",
            28,
            "5"
        });
        dt.Rows.Add(new object[] {
            "2",
            "8",
            31,
            "2"
        });
        dt.Rows.Add(new object[] {
            "2",
            "4",
            31,
            "4"
        });
        dt.Rows.Add(new object[] {
            "3",
            "7",
            37,
            "3"
        });
        dt.Rows.Add(new object[] {
            "4",
            "4",
            40,
            "1"
        });

        DataView dv = dt.DefaultView;
        // use a stringbuilder to hold the sortexpression for the dataview
        StringBuilder sbSortExpression = new StringBuilder();
        if (SortExpressions.Count > 0)
        {
            string[] myKeys = new string[SortExpressions.Count + 1];
            SortExpressions.Keys.CopyTo(myKeys, 0);
            for (int i = 0; i <= SortExpressions.Count - 1; i++)
            {
                sbSortExpression.Append(myKeys[i]);
                sbSortExpression.Append(" ");
                sbSortExpression.Append(SortExpressions[myKeys[i]]);
                if (i != SortExpressions.Count - 1)
                {
                    sbSortExpression.Append(", ");
                }

            }
            lblSortExpression.Text = sbSortExpression.ToString();

            // usually we would send that sort-expression now to SQL via some stored-procedure
            dv.Sort = sbSortExpression.ToString();
        }
        else
        {
            lblSortExpression.Text = string.Empty;
        }

        GridView1.DataSource = dv;
        GridView1.DataBind();
        PositionGlyph(GridView1, dv.Sort.ToString(), dt);


    }

    private void PositionGlyph(GridView GridView1, string p,DataTable dt)
    {
        if ((GridView1.Rows.Count == 0) || (string.IsNullOrEmpty(p)))
            return;

        Image glyph = new Image();
        glyph.EnableTheming = false;

        string[] words = p.Split(',');

        foreach (string word in words)
        {
            string[] SortType = word.Split(' ');
            if (SortType[SortType.Length - 1] == SortOrder.Ascending.ToString().Substring(0, 3).ToUpper())
                glyph.ImageUrl = "~/Images/down_arrow.png";

            else
                glyph.ImageUrl = "~/Images/up_arrow.png";

            int columnindex = dt.Columns[SortType[SortType.Length - 2].ToString()].Ordinal;
            GridView1.HeaderRow.Cells[columnindex].Controls.Add(glyph);
            //for (int x = 0; x < dt.Columns.Count; x++)
            //{
            //    if (SortType[SortType.Length - 2].ToString()== dt.Columns[x].ColumnName)
            //    {
            //        GridView1.HeaderRow.Cells[x].Controls.Add(glyph);
            //        break;
            //    }
            //}

        }

    }

    protected void GridView1_Sorting(object sender, System.Web.UI.WebControls.GridViewSortEventArgs e)
    {
        m_ldSortExpression = SortExpressions;

        if (!m_ldSortExpression.Contains(e.SortExpression))
        {
            m_ldSortExpression.Add(e.SortExpression, e.SortDirection.ToString().Replace("Ascending", "ASC").Replace("Descending", "DESC"));
        }
        else
        {
            // Get sort direction
            string strSortDirection = m_ldSortExpression[e.SortExpression].ToString();
            // Was it ascending?
            if (strSortDirection == "ASC")
            {
                // Yes, so sort in desc
                m_ldSortExpression[e.SortExpression] = "DESC";
            }
            else if (strSortDirection == "DESC")
            {
                // it is descending
                // remove the sort order
                m_ldSortExpression.Remove(e.SortExpression);
            }
        }

        SortExpressions = m_ldSortExpression;
        BindData();
    }
    public _Default()
    {
        Load += Page_Load;
    }

}

一切正常,即使多次排序,但列标题中的排序箭头未正确显示。我认为问题出在 PositionGlyph Method.Asc 或 Desc 箭头仅显示最后单击的标题。我想显示所有列的排序方向。请帮助我

4

2 回答 2

1

Use This:

DataView m_DataView = new DataView(dt);
m_DataView.Sort =ColumnName1 + " ASC, " + ColumnName2 + " ASC, " + ColumnName3 + " ASC";

Hope this help.

于 2013-04-01T12:22:12.483 回答
0

您可以在 RowCreated 事件中显示用于对 gridview 列进行排序行为的箭头,就像这样我通常这样做

protected void GridView1_RowCreated(object sender, GridViewRowEventArgs e)
{
    if (e.Row.RowType == DataControlRowType.Header)
    {
        foreach (TableCell tc in e.Row.Cells)
        {
            if (tc.HasControls())
            {
                // search for the header link
                LinkButton lnk = (LinkButton)tc.Controls[0];
                if (lnk != null && GridView1.SortExpression == lnk.CommandArgument)
                {
                    // inizialize a new image
                    System.Web.UI.WebControls.Image img = new System.Web.UI.WebControls.Image();
                    // setting the dynamically URL of the image
                    img.ImageUrl = "~/img/ico_" + (GridView1.SortDirection == SortDirection.Ascending ? "asc" : "desc") + ".gif";
                    // adding a space and the image to the header link
                    tc.Controls.Add(new LiteralControl(" "));
                    tc.Controls.Add(img);

                }
            }
        }
    }
}

它还可以在列的升序和降序排序上切换图像

代码实际上做的是循环遍历 GridView Header 以搜索 LinkBut​​ton(仅当设置了 SortExpression 属性时,框架才会创建它)。然后,如果找到的 LinkBut​​ton 是排序字段,那么它将图像显示到输出,仅此而已

请看这个样本

于 2013-04-01T12:16:13.427 回答