ASP.Net2.0 GridView 多列排序,显示排序图标,分页

  最近在使用ASP.net 2.0的GridView 控件时,发现排序与分页功能Microsoft实现的都很简单,比如排序,在点击列名的时候来触发整页的PostBack,然后排序,但是在列头上没有一个显示升序降序的图标,这会让最终用户使用时很迷惑,因为不知道是升序了还是降序了,所以今天首先解决的第一问题就是升序降序在列上显示图标,第二要解决的问题是默认GridView按列排序只能排一列的,也就是不能进行多列排序,而在实际应用中仅仅按照一列来排序是不能满足业务需求的,第三是GridView 分页问题,GridView预定义的分页页码显示,比较简单,而实际应用中,分页可能不是只显示首页,上一页,下一页,末页,或者是数字的页码那么简单,应该更需要,跳转,当前的页码,总页数等,更详尽的信息。

  第一:GridView 多列排序与排序图标显示

  首先我们可以新建一个类库程序,主要需要引用System.Web.Dll文件

  然后新建一个类,这个类继承与GridView控件,我们只需要对部分方法进行重新即可。

  我的演示的例子,采用了单列排序,如果启用多列排序,把控件的AllowMultiColumnSorting设置为True就是

  多列排序。

  1    public class WebGridView:GridView

  2    {

  3        属性#region 属性

  4        /**//// <summary>

  5        /// 是否启用或者禁止多列排序

  6        /// </summary>

  7        [

  8        Description("是否启用多列排序功能"),

  9        Category("排序"),

  10        DefaultValue("false"),

  11        ]

  12        public bool AllowMultiColumnSorting

  13        {

  14            get

  15            {

  16                object o = ViewState["EnableMultiColumnSorting"];

  17                return (o != null ? (bool)o : false);

  18            }

  19            set

  20            {

  21                AllowSorting = true;

  22                ViewState["EnableMultiColumnSorting"] = value;

  23            }

  24        }

  25        /**//// <summary>

  26        /// 升序时显示图标

  27        /// </summary>

  28        [

  29        Description("升序时显示图标"),

  30        Category("排序"),

  31        Editor("System.Web.UI.Design.UrlEditor", typeof(System.Drawing.Design.UITypeEditor)),

  32        DefaultValue(""),

  33

  34        ]

  35        public string SortAscImageUrl

  36        {

  37            get

  38            {

  39                object o = ViewState["SortImageAsc"];

  40                return (o != null ? o.ToString() : "");

  41            }

  42            set

  43            {

  44                ViewState["SortImageAsc"] = value;

  45            }

  46        }

  47        /**//// <summary>

  48        /// 降序时显示图标

  49        /// </summary>

  50        [

  51        Description("降序时显示图标"),

  52        Category("排序"),

  53        Editor("System.Web.UI.Design.UrlEditor", typeof(System.Drawing.Design.UITypeEditor)),

  54        DefaultValue(""),

  55        ]

  56        public string SortDescImageUrl

  57        {

  58            get

  59            {

  60                object o = ViewState["SortImageDesc"];

  61                return (o != null ? o.ToString() : "");

  62            }

  63            set

  64            {

  65                ViewState["SortImageDesc"] = value;

  66            }

  67        }

  68        #endregion

  69        重写方法#region 重写方法

  70        protected override void OnSorting(GridViewSortEventArgs e)

  71        {

  72            if (AllowMultiColumnSorting)

  73            {

  74                e.SortExpression = GetSortExpression(e);

  75            }

  76

  77            base.OnSorting(e);

  78        }

  79        protected override void OnRowCreated(GridViewRowEventArgs e)

  80        {

  81            if (e.Row.RowType == DataControlRowType.Header)

  82            {

  83                if (SortExpression != String.Empty)

  84                {

  85                    DisplaySortOrderImages(SortExpression, e.Row);

  86                    this.CreateRow(0, 0, DataControlRowType.EmptyDataRow, DataControlRowState.Normal);

  87                }

  88            }

  89            base.OnRowCreated(e);

  90        }

  91        #endregion

  92        受保护的方法#region 受保护的方法

  93        /**//// <summary>

  94        ///  获取排序表达式

  95        /// </summary>

  96        protected string GetSortExpression(GridViewSortEventArgs e)

  97        {

  98            string[] sortColumns = null;

  99            string sortAttribute = SortExpression;

  100

  101            if (sortAttribute != String.Empty)

  102            {

  103                sortColumns = sortAttribute.Split(",".ToCharArray());

  104            }

  105            if (sortAttribute.IndexOf(e.SortExpression) > 0 || sortAttribute.StartsWith(e.SortExpression))

  106            {

  107                sortAttribute = ModifySortExpression(sortColumns, e.SortExpression);

  108            }

  109            else

  110            {

  111                sortAttribute += String.Concat(",", e.SortExpression, " ASC ");

  112            }

  113            return sortAttribute.TrimStart(",".ToCharArray()).TrimEnd(",".ToCharArray());

  114

  115        }

  116        /**//// <summary>

  117        ///  修改排序顺序

  118        /// </summary>

  119        protected string ModifySortExpression(string[] sortColumns, string sortExpression)

  120        {

  121            string ascSortExpression = String.Concat(sortExpression, " ASC ");

  122            string descSortExpression = String.Concat(sortExpression, " DESC ");

  123

  124            for (int i = 0; i < sortColumns.Length; i++)

  125            {

  126

  127                if (ascSortExpression.Equals(sortColumns[i]))

  128                {

  129                    sortColumns[i] = descSortExpression;

  130                }

  131

  132                else if (descSortExpression.Equals(sortColumns[i]))

  133                {

  134                    Array.Clear(sortColumns, i, 1);

  135                }

  136            }

  137

  138            return String.Join(",", sortColumns).Replace(",,", ",").TrimStart(",".ToCharArray());

  139

  140        }

  141        /**//// <summary>

  142        ///  获取当前的表达式对所选列进行排序

  143        /// </summary>

  144        protected void SearchSortExpression(string[] sortColumns, string sortColumn, out string sortOrder, out int sortOrderNo)

  145        {

  146            sortOrder = "";

  147            sortOrderNo = -1;

  148            for (int i = 0; i < sortColumns.Length; i++)

  149            {

  150                if (sortColumns[i].StartsWith(sortColumn))

  151                {

  152                    sortOrderNo = i + 1;

  153                    if (AllowMultiColumnSorting)

  154                    {

  155                        sortOrder = sortColumns[i].Substring(sortColumn.Length).Trim();

  156                    }

  157                    else

  158                    {

  159                        sortOrder = ((SortDirection == SortDirection.Ascending) ? "ASC" : "DESC");

  160                    }

  161                }

  162            }

  163        }

  164        /**//// <summary>

  165        ///  绘制升序降序的图片

  166        /// </summary>

  167        protected void DisplaySortOrderImages(string sortExpression, GridViewRow dgItem)

  168        {

  169            string[] sortColumns = sortExpression.Split(",".ToCharArray());

  170

  171            for (int i = 0; i < dgItem.Cells.Count; i++)

  172            {

  173                if (dgItem.Cells[i].Controls.Count > 0 && dgItem.Cells[i].Controls[0] is LinkButton)

  174                {

  175                    string sortOrder;

  176                    int sortOrderNo;

  177                    string column = ((LinkButton)dgItem.Cells[i].Controls[0]).CommandArgument;

  178                    SearchSortExpression(sortColumns, column, out sortOrder, out sortOrderNo);

  179                    if (sortOrderNo > 0)

  180                    {

  181                        string sortImgLoc = (sortOrder.Equals("ASC") ? SortAscImageUrl : SortDescImageUrl);

  182

  183                        if (sortImgLoc != String.Empty)

  184                        {

  185                            Image imgSortDirection = new Image();

  186                            imgSortDirection.ImageUrl = sortImgLoc;

  187                            dgItem.Cells[i].Controls.Add(imgSortDirection);

  188

  189                        }

  190                        else

  191                        {

  192

  193                            if (AllowMultiColumnSorting)

  194                            {

  195                                Literal litSortSeq = new Literal();

  196                                litSortSeq.Text = sortOrderNo.ToString();

  197                                dgItem.Cells[i].Controls.Add(litSortSeq);

  198

  199                            }

  200                        }

  201                    }

  202                }

  203            }

  204

  205        }

  206        #endregion

  207    }

  第二:详尽的分页信息显示,此功能没有封装成控件形式,直接在GridView_DataBound事件中对尾页操作即可。

  下面是多列排序与分页显示代码的演示

  <script runat="server">

  void PageDropDownList_SelectedIndexChanged(Object sender, EventArgs e)

  {

  GridViewRow pagerRow = CustomersGridView.BottomPagerRow;

  DropDownList pageList = (DropDownList)pagerRow.Cells[0].FindControl("PageDropDownList");

  CustomersGridView.PageIndex = pageList.SelectedIndex;

  }

  void CustomersGridView_DataBound(Object sender, EventArgs e)

  {

  GridViewRow pagerRow = CustomersGridView.BottomPagerRow;

  LinkButton linkBtnFirst = (LinkButton)pagerRow.Cells[0].FindControl("linkBtnFirst");

  LinkButton linkBtnPrev = (LinkButton)pagerRow.Cells[0].FindControl("linkBtnPrev");

  LinkButton linkBtnNext = (LinkButton)pagerRow.Cells[0].FindControl("linkBtnNext");

  LinkButton linkBtnLast = (LinkButton)pagerRow.Cells[0].FindControl("linkBtnLast");

  if (CustomersGridView.PageIndex == 0)

  {

  linkBtnFirst.Enabled = false;

  linkBtnPrev.Enabled = false;

  }

  else if (CustomersGridView.PageIndex == CustomersGridView.PageCount-1)

  {

  linkBtnLast.Enabled  = false;

  linkBtnNext.Enabled = false;

  }

  else if (CustomersGridView.PageCount<=0)

  {

  linkBtnFirst.Enabled = false;

  linkBtnPrev.Enabled = false;

  linkBtnNext.Enabled = false;

  linkBtnLast.Enabled = false;

  }

  DropDownList pageList = (DropDownList)pagerRow.Cells[0].FindControl("PageDropDownList");

  Label pageLabel = (Label)pagerRow.Cells[0].FindControl("CurrentPageLabel");

  if (pageList != null)

  {

  for (int i = 0; i < CustomersGridView.PageCount; i++)

  {

  int pageNumber = i + 1;

  ListItem item = new ListItem(pageNumber.ToString() + "/" + CustomersGridView.PageCount.ToString(), pageNumber.ToString());

  if (i == CustomersGridView.PageIndex)

  {

  item.Selected = true;

  }

  pageList.Items.Add(item);

  }

  }

  if (pageLabel != null)

  {

  int currentPage = CustomersGridView.PageIndex + 1;

  pageLabel.Text = "当前页: " + currentPage.ToString() +

  " / " + CustomersGridView.PageCount.ToString();

  }

  }

  </script>

  <html>

  <body>

  <form id="Form1" runat="server">

  <h3>

  GridView PagerTemplate Example</h3>

  <asp:WebGridView ID="CustomersGridView" DataSourceID="CustomersSqlDataSource" AutoGenerateColumns="true"

  AllowPaging="true" OnDataBound="CustomersGridView_DataBound" SortAscImageUrl="~\images\arrow-up.gif" SortDescImageUrl="~\images\arrow-down.gif" runat="server" AllowSorting="True" Width="723px">

  <PagerStyle ForeColor="Blue" BackColor="LightBlue" />

  <PagerTemplate>

  <table width="100%">

  <tr>

  <td width="70%">

  <asp:Label ID="MessageLabel" ForeColor="Blue" Text="页码:" runat="server" />

  <asp:DropDownList ID="PageDropDownList" AutoPostBack="true" OnSelectedIndexChanged="PageDropDownList_SelectedIndexChanged"

  runat="server" />

  <asp:LinkButton CommandName="Page" CommandArgument="First" ID="linkBtnFirst" runat="server">首页</asp:LinkButton>

  <asp:LinkButton CommandName="Page" CommandArgument="Prev" ID="linkBtnPrev" runat="server">上一页</asp:LinkButton>

  <asp:LinkButton CommandName="Page" CommandArgument="Next" ID="linkBtnNext" runat="server">下一页</asp:LinkButton>

  <asp:LinkButton CommandName="Page" CommandArgument="Last" ID="linkBtnLast" runat="server">末页</asp:LinkButton>

  </td>

  <td width="70%" align="right">

  <asp:Label ID="CurrentPageLabel" ForeColor="Blue" runat="server" />

  </td>

  </tr>

  </table>

  </PagerTemplate>

  </asp:WebGridView>

  <asp:SqlDataSource ID="CustomersSqlDataSource" SelectCommand="Select [CustomerID], [CompanyName], [Address], [City], [PostalCode], [Country] From [Customers]"

  ConnectionString="<%$ ConnectionStrings:NorthWindConnectionString%>" runat="server">

  </asp:SqlDataSource>

  </form>

  </body>

  </html>