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

[源码下载]

扩展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>
/*测试版的实现 结束*/ 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要给Yii2-GridView中的自定义字段增加排序功能,可以通过以下步骤实现: 1. 在GridView的columns属性中,为自定义字段添加‘attribute’属性(指定排序用的字段),‘label’属性(指定在表头显示的名称),以及‘value’属性(指定自定义字段的值)。 2. 在GridView的dataProvider属性中,为排序用的字段添加一个Sort属性。 3. 在GridView中的排序链接中,为自定义字段添加一个sort参数,指定排序用的字段。 以下是一个示例代码: ``` use yii\grid\GridView; use yii\data\ActiveDataProvider; use yii\data\Sort; $dataProvider = new ActiveDataProvider([ 'query' => $query, 'sort' => [ 'attributes' => [ 'custom_field' => [ 'asc' => ['custom_field' => SORT_ASC], 'desc' => ['custom_field' => SORT_DESC], 'label' => 'Custom Field', ], ], ], ]); echo GridView::widget([ 'dataProvider' => $dataProvider, 'columns' => [ 'id', 'name', [ 'attribute' => 'custom_field', 'label' => 'Custom Field', 'value' => function ($model) { return $model->customField; } ], ], 'sorter' => [ 'attributes' => [ 'custom_field' => [ 'asc' => ['custom_field' => SORT_ASC], 'desc' => ['custom_field' => SORT_DESC], ], ], ], ]); ``` 在以上代码中,我们为自定义字段‘custom_field’添加了一个Sort属性,然后在GridView中为该字段添加了‘attribute’、‘label’和‘value’属性。最后,在排序链接中为自定义字段添加了‘sort’参数,指定排序用的字段。这样就可以为Yii2-GridView中的自定义字段增加排序功能了。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值