扩展GridView控件(2) - 复合排序和排序状态提示

来源:互联网 发布:测试apm的软件 编辑:程序博客网 时间:2024/06/05 10:50

[源码下载]

扩展GridView控件(2) - 复合排序和排序状态提示

 

作者:webabcd


/*正式版的实现 开始*/
介绍
扩展GridView控件:
对多个字段进行复合排序;升序、降序的排序状态提示

使用方法(设置SmartSorting复合属性):
AllowSortTip - 是否启用排序提示
AllowMultiSorting - 是否启用复合排序
SortAscImageUrl - 升序提示图片的URL(不设置则使用默认图片)
SortDescImageUrl - 降序提示图片的URL(不设置则使用默认图片)
SortAscText - 升序提示文本
SortDescText - 降序提示文本


关键代码
using System;
using System.Collections.Generic;
using System.Text;

using System.Web.UI.WebControls;
using System.Web.UI;

namespace YYControls.SmartGridViewFunction
{
    /**//// <summary>
    /// 扩展功能:复合排序和排序状态提示
    /// </summary>
    public class SmartSortingFunction : ExtendFunction
    {
        /**//// <summary>
        /// 构造函数
        /// </summary>
        public SmartSortingFunction()
            : base()
        {

        }

        /**//// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="sgv">SmartGridView对象</param>
        public SmartSortingFunction(SmartGridView sgv)
            : base(sgv)
        {

        }

        /**//// <summary>
        /// 扩展功能的实现
        /// </summary>
        protected override void Execute()
        {
            // 开启SmartGridView的排序功能
            // this._sgv.AllowSorting = true;

            this._sgv.Sorting += new System.Web.UI.WebControls.GridViewSortEventHandler(_sgv_Sorting);
            this._sgv.RowDataBoundCell += new SmartGridView.RowDataBoundCellHandler(_sgv_RowDataBoundCell);
        }

        /**//// <summary>
        /// SmartGridView的RowDataBoundCell事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="gvtc"></param>
        void _sgv_RowDataBoundCell(object sender, GridViewTableCell gvtc)
        {
            if (!String.IsNullOrEmpty(this._sgv.SortExpression)
                && this._sgv.SmartSorting.AllowSortTip
                && gvtc.RowType == DataControlRowType.Header)
            {
                // 显示排序状态提示
                DisplaySortTip(this._sgv.SortExpression, gvtc.TableCell);
            }
        }

        /**//// <summary>
        /// Sorting事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void _sgv_Sorting(object sender, System.Web.UI.WebControls.GridViewSortEventArgs e)
        {
            // 如果允许复合排序的话,则设置复合排序表达式
            if (this._sgv.SmartSorting.AllowMultiSorting)
            {
                e.SortExpression = GetSortExpression(e);
            }
        }

        /**//// <summary>
        /// 获得复合排序表达式
        /// </summary>
        /// <param name="e"></param>
        /// <returns></returns>
        protected string GetSortExpression(GridViewSortEventArgs e)
        {
            string[] sortColumns = null;
            string sortAttribute = this._sgv.SortExpression;

            if (!String.IsNullOrEmpty(sortAttribute))
            {
                sortColumns = sortAttribute.Split(',');
            }

            // 如果原排序表达式有当前排序字段
            if (sortAttribute.IndexOf(e.SortExpression) != -1)
            {
                // 更新排序表达式
                sortAttribute = ModifySortExpression(sortColumns, e.SortExpression);
            }
            else
            {
                // 为原排序表达式添加新的排序规则(升序)
                sortAttribute += String.Concat(",", e.SortExpression, " ASC");
            }

            return sortAttribute.Trim(',');
        }

        /**//// <summary>
        /// 更新排序表达式
        /// </summary>
        /// <param name="sortColumns">各个字段的排序表达式数组</param>
        /// <param name="sortExpression">当前需要排序的字段(该字段在sortColumns数组中)</param>
        /// <returns></returns>
        protected string ModifySortExpression(string[] sortColumns, string sortExpression)
        {
            // 当前需要排序的字段的升序表达式
            string ascSortExpression = String.Concat(sortExpression, " ASC");
            // 当前需要排序的字段的降序表达式
            string descSortExpression = String.Concat(sortExpression, " DESC");

            for (int i = 0; i < sortColumns.Length; i++)
            {
                // 各个字段的排序表达式数组中,有当前需要排序的字段的升序表达式
                if (ascSortExpression.Equals(sortColumns[i]))
                {
                    // 当前排序字段由升序变为降序
                    sortColumns[i] = descSortExpression;
                    break;
                }
                // 各个字段的排序表达式数组中,有当前需要排序的字段的降序表达式
                else if (descSortExpression.Equals(sortColumns[i]))
                {
                    // 从各个字段的排序表达式数组中,删除当前需要排序的字段
                    Array.Clear(sortColumns, i, 1);
                    break;
                }
            }

            return String.Join(",", sortColumns).Replace(",,", ",").Trim(',');
        }

        /**//// <summary>
        /// 显示排序状态提示
        /// </summary>
        /// <param name="sortExpression">排序表达式</param>
        /// <param name="tc">Header的TableCell</param>
        protected void DisplaySortTip(string sortExpression, TableCell tc)
        {
            string[] sortColumns = sortExpression.Split(',');

            if (tc.Controls.Count > 0 && tc.Controls[0] is LinkButton)
            {
                string columnName = ((LinkButton)tc.Controls[0]).CommandArgument;

                int sortOrderIndex = Array.FindIndex(sortColumns, delegate(string s) { return s.IndexOf(columnName) != -1; });

                // 如果排序表达式中有当前列
                if (sortOrderIndex != -1)
                {
                    // 当前列应该是升序还是降序(区分两种情况:复合排序和非复合排序)
                    SortDirection sortDirection = SortDirection.Ascending;
                    if (this._sgv.SmartSorting.AllowMultiSorting && sortColumns[sortOrderIndex].IndexOf("DESC") != -1)
                    {
                        sortDirection = SortDirection.Descending;
                    }
                    else if (!this._sgv.SmartSorting.AllowMultiSorting && this._sgv.SortDirection == SortDirection.Descending)
                    {
                        sortDirection = SortDirection.Descending;
                    }

                    // 排序状态提示(图片地址)
                    string sortImageUrl = null;
                    // 排序状态提示(文本)
                    string sortText = null;
                    if (sortDirection == SortDirection.Ascending)
                    {
                        sortText = this._sgv.SmartSorting.SortAscText;

                        sortImageUrl = this._sgv.SmartSorting.SortAscImageUrl;

                        if (String.IsNullOrEmpty(sortImageUrl))
                        {
                            sortImageUrl =
                                this._sgv.Page.ClientScript.GetWebResourceUrl
                                (
                                    this.GetType(),
                                    "YYControls.SmartGridView.Resources.Asc.gif"
                                );
                        }
                    }
                    else
                    {
                        sortText = this._sgv.SmartSorting.SortDescText;

                        sortImageUrl = this._sgv.SmartSorting.SortDescImageUrl;

                        if (String.IsNullOrEmpty(sortImageUrl))
                        {
                            sortImageUrl =
                                this._sgv.Page.ClientScript.GetWebResourceUrl
                                (
                                    this.GetType(),
                                    "YYControls.SmartGridView.Resources.Desc.gif"
                                );
                        }
                    }

                    // 添加排序状态提示图片
                    Image imgSortDirection = new Image();
                    imgSortDirection.ImageUrl = sortImageUrl;
                    tc.Controls.Add(imgSortDirection);

                    // 添加排序状态提示文本
                    tc.Controls.Add(new LiteralControl(sortText));

                    if (this._sgv.SmartSorting.AllowMultiSorting)
                    {
                        // 添加排序状态提示序号
                        tc.Controls.Add(new LiteralControl((sortOrderIndex + 1).ToString()));
                    }

                    不用资源文件,又没有设置排序状态提示时的逻辑(已经注释掉了)#region 不用资源文件,又没有设置排序状态提示时的逻辑(已经注释掉了)
                    /**///// 添加排序状态提示图标
                    //Label lblSortDirection = new Label();
                    /**///// 被注释的代码使用的是webdings,但是FF不支持,所以放弃了
                    //// lblSortDirection.Font.Name = "webdings";
                    //// lblSortDirection.EnableTheming = false;
                    //if (sortDirection == SortDirection.Ascending)
                    //{
                    //    // lblSortDirection.Text = "5";
                    //    lblSortDirection.Text = "▲";
                    //}
                    //else
                    //{
                    //    // lblSortDirection.Text = "6";
                    //    lblSortDirection.Text = "▼";
                    //}
                    //tc.Controls.Add(lblSortDirection);

                    //if (this._sgv.SmartSorting.AllowMultiSorting)
                    //{
                    //    // 添加排序状态提示序号
                    //    tc.Controls.Add(new LiteralControl((sortOrderIndex + 1).ToString()));
                    //}
                    #endregion

                } // if (sortOrderIndex != -1)
            } // if (tc.Controls.Count > 0 && tc.Controls[0] is LinkButton)
        }
    }
}

/*正式版的实现 结束*/

/*测试版的实现 开始*/
介绍
在用GridView自带的排序功能排序时,无法直观的知道当前是通过哪个字段排序?是升序还是降序?所以扩展一下,用图片或文字的形式来提示一下当前是根据哪个字段排序,是升序还是降序。


控件开发
1、新建一个继承自GridView的类。
    /**//// <summary>
    /// 继承自GridView
    /// </summary>
    [
    ToolboxData(@"<{0}:SmartGridView runat='server'></{0}:SmartGridView>"),
    ParseChildren(true),
    PersistChildren(false)
    ]
    public class SmartGridView : GridView
    {
    }
2、新建一个SortTip实体类,有4个属性,分别是降序提示图片、升序提示图片、降序提示文本和升序提示文本
using System;
using System.Collections.Generic;
using System.Text;

using System.ComponentModel;

namespace YYControls.SmartGridView
{
    /**//// <summary>
    /// 排序提示类
    /// </summary>
    [TypeConverter(typeof(ExpandableObjectConverter))]
    public class SortTip
    {
        private string _sortDescImage;
        /**//// <summary>
        /// 降序提示图片
        /// </summary>
        [
        Description("降序提示图片"),
        Category("扩展"),
        Editor("System.Web.UI.Design.UrlEditor", typeof(System.Drawing.Design.UITypeEditor)),
        DefaultValue(""),
        NotifyParentProperty(true)
        ]
        public string SortDescImage
        {
            get { return _sortDescImage; }
            set { _sortDescImage = value; }
        }

        private string _sortAscImage;
        /**//// <summary>
        /// 升序提示图片
        /// </summary>
        [
        Description("升序提示图片"),
        Category("扩展"),
        Editor("System.Web.UI.Design.UrlEditor", typeof(System.Drawing.Design.UITypeEditor)),
        DefaultValue(""),
        NotifyParentProperty(true)
        ]
        public string SortAscImage
        {
            get { return _sortAscImage; }
            set { _sortAscImage = value; }
        }

        private string _sortDescText;
        /**//// <summary>
        /// 降序提示文本
        /// </summary>
        [
        Description("降序提示文本"),
        Category("扩展"),
        DefaultValue(""),
        NotifyParentProperty(true)
        ]
        public string SortDescText
        {
            get { return _sortDescText; }
            set { _sortDescText = value; }
        }

        private string _sortAscText;
        /**//// <summary>
        /// 升序提示文本
        /// </summary>
        [
        Description("升序提示文本"),
        Category("扩展"),
        DefaultValue(""),
        NotifyParentProperty(true)
        ]
        public string SortAscText
        {
            get { return _sortAscText; }
            set { _sortAscText = value; }
        }

        /**//// <summary>
        /// ToString()
        /// </summary>
        /// <returns></returns>
        public override string ToString()
        {
            return "SortTip";
        }
    }
}

3、在继承自GridView的那个类中加1个复杂对象属性,这个复杂对象就是第2步创建的那个SortTip
        private SortTip _sortTip;
        /**//// <summary>
        /// 排序提示信息
        /// </summary>
        [
        Description("排序提示信息"),
        Category("扩展"),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
        PersistenceMode(PersistenceMode.InnerProperty)
        ]
        public virtual SortTip SortTip
        {
            get
            {
                if (_sortTip == null)
                {
                    _sortTip = new SortTip();
                }
                return _sortTip;
            }
        }
4、重写OnRowDataBound实现给字段标题加上排序状态的功能。主要是根据GridView.SortExpression和GridView.SortDirection来实现这样的功能。
        /**//// <summary>
        /// OnRowDataBound
        /// </summary>
        /// <param name="e"></param>
        protected override void OnRowDataBound(GridViewRowEventArgs e)
        {
            if (e.Row.RowType == DataControlRowType.Header)
            {
                // GridViewRow的每个TableCell
                for (int i = 0; i < e.Row.Cells.Count; i++)
                {
                    // TableCell里有一个Control并且是LinkButton
                    if (e.Row.Cells[i].Controls.Count == 1 && e.Row.Cells[i].Controls[0] is LinkButton)
                    {
                        // LinkButton的命令参数等于排序字段
                        if (((LinkButton)e.Row.Cells[i].Controls[0]).CommandArgument == this.SortExpression)
                        {
                            Image img = null;
                            Label lbl = null;

                            // 升序
                            if (this.SortDirection == SortDirection.Ascending)
                            {
                                // 升序图片
                                if (!String.IsNullOrEmpty(_sortTip.SortAscImage))
                                {
                                    img = new Image();
                                    img.ImageUrl = base.ResolveUrl(_sortTip.SortAscImage);
                                }
                                // 升序文字
                                if (!String.IsNullOrEmpty(_sortTip.SortAscText))
                                {
                                    lbl = new Label();
                                    lbl.Text = _sortTip.SortAscText;
                                }
                            }
                            // 降序
                            else if (this.SortDirection == SortDirection.Descending)
                            {
                                // 降序图片
                                if (!String.IsNullOrEmpty(_sortTip.SortDescImage))
                                {
                                    img = new Image();
                                    img.ImageUrl = base.ResolveUrl(_sortTip.SortDescImage);
                                }
                                // 降序文字
                                if (!String.IsNullOrEmpty(_sortTip.SortDescText))
                                {
                                    lbl = new Label();
                                    lbl.Text = _sortTip.SortDescText;
                                }
                            }

                            // TableCell里加上图片
                            if (img != null)
                            {
                                e.Row.Cells[i].Controls.Add(img);
                            }
                            // TableCell里加上文字
                            if (lbl != null)
                            {
                                e.Row.Cells[i].Controls.Add(lbl);
                            }
                        }
                    }
                }
            }

            base.OnRowDataBound(e);
        }


控件使用
添加这个控件到工具箱里,然后拖拽到webform上,设置其SortTip下的4个属性即可。SortAscImage是升序提示图片;SortAscText是升序提示文本;SortDescImage是降序提示图片;SortDescText是降序提示文本
ObjData.cs
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;

using System.ComponentModel;

/**//// <summary>
/// OjbData 的摘要说明
/// </summary>
public class OjbData
{
    public OjbData()
    {
        //
        // TODO: 在此处添加构造函数逻辑
        //
    }

    [DataObjectMethod(DataObjectMethodType.Select, true)]
    public DataTable Select()
    {
        DataTable dt = new DataTable();
        dt.Columns.Add("no", typeof(string));
        dt.Columns.Add("name", typeof(string));

        for (int i = 0; i < 30; i++)
        {
            DataRow dr = dt.NewRow();
            dr[0] = "no" + i.ToString().PadLeft(2, '0');
            dr[1] = "name" + i.ToString().PadLeft(2, '0');

            dt.Rows.Add(dr);
        }

        return dt;
    }
}

Default.aspx
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="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 runat="server">
    <title>无标题页</title>
</head>
<body>
    <form id="form1" runat="server">
        <div>
            <yyc:SmartGridView ID="SmartGridView1" runat="server" AutoGenerateColumns="True"
                AllowSorting="True" DataSourceID="ObjectDataSource1">
                <Columns>
                    <asp:ButtonField CommandName="ConfirmTest" Text="确认按钮测试" />
                </Columns>
                <SortTip SortAscImage="~/Images/asc.gif" SortDescImage="~/Images/desc.gif" />
            </yyc:SmartGridView>
            <asp:ObjectDataSource ID="ObjectDataSource1" runat="server" SelectMethod="Select"
                TypeName="OjbData"></asp:ObjectDataSource>
        </div>
  </form>
</body>
</html>
/*测试版的实现 结束*/ 

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 行驶证驾驶证都遗失了怎么办 c1增驾b2没考过怎么办 没驾照买车怎么办行驶证 广州车辆年审加装踏板怎么办 租车感觉违章了 怎么办 武汉驾照扣12分怎么办 驾驶证照片泡水不清楚怎么办 驾驶证过了180天怎么办 天津有公司执照怎么办落户 温州车在上海年审手续怎么办 广东小高考考了d怎么办 深圳开摩托抓到怎么办 深圳车卖了车牌怎么办 a1驾照时期过了怎么办 b1驾照扣了12分怎么办 北京的驾照换证怎么办 b2汽车驾驶证年审过期几天怎么办 上海驾照到期人在外地怎么办 交警开的罚单交不了怎么办 珠海交警微信交罚单扣分怎么办 驾驶证违法罚款单子没有了怎么办 转账密码输错3次怎么办 汽车违章扣6分怎么办 汽车扣了72分年检怎么办 汽车扣了50分怎么办 汽车扣了15分怎么办 汽车扣了27分怎么办 汽车扣了40分怎么办 行驶证掉了怎么办 异地 高速上没带驾驶证行驶证怎么办 身份证驾驶证行驶证都丢了怎么办 驾驶证年审过期一个月怎么办 柴油车辆年检尾气不合格怎么办 驾驶证过期了5天怎么办 过了审车时间怎么办 骑车没带行驶证怎么办 轿车行驶证丢了怎么办 车子没年检被扣怎么办 上海车辆年检过期了怎么办 行驶证过期十天怎么办 行驶证盖章满了怎么办