ASP.NET GridView动态显示隐藏列,并保存客户的配置(用户控件Cookie版)

示例源码:Download


ASP.NET开发中,会遇到有些客户提出这样需求,可根据需求编辑GridView列显示以及隐藏,这个用户控件就是为了这个需求而生。
自动从GridView中获取所有Visible=true的列,加入到CheckBoxList,并配合Cookie实现本次配置后,下次依然有效。

应用场景效果图:



使用指南:

1、引用用户控件

2、后台初始化用户控件,Page_Load方法体实现委托,传入目标GridView

protected void Page_Load(object sender, EventArgs e)
{
    this.ucGridViewLayout.SelectedIndexChangedEvent += new Unisoft.ICS.Web.UserControls.Common.GridViewLayout.EventDelegate(ucGridViewLayout_SelectedIndexChangedEvent);
    if (!Page.IsPostBack)
    {
        //GridView绑定

        //初始化用户控件
        this.ucGridViewLayout.BindGridViewColumn(this.gvProductList);
    }
}

//控件回调执行更新列
void ucGridViewLayout_SelectedIndexChangedEvent()
{
    this.ucGridViewLayout.UpdateGridViewColumn(this.gvProductList);
    this.uppProductList.Update();//如果GridView包了一层局部刷新,则需要执行更新
}

新建用户控件GridViewLayout.ascx

<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="GridViewLayout.ascx.cs" Inherits="Unisoft.ICS.Web.UserControls.Common.GridViewLayout" %>
<asp:UpdatePanel ID="uppGridViewShow" runat="server" UpdateMode="Conditional">
    <ContentTemplate>
        <asp:CheckBoxList ID="ChkGridViewColumnList" runat="server" RepeatDirection="Horizontal"
            Width="100%" RepeatColumns="14" RepeatLayout="Table" AutoPostBack="true" OnSelectedIndexChanged="ChkGridViewColumnList_SelectedIndexChanged">
        </asp:CheckBoxList>
    </ContentTemplate>
</asp:UpdatePanel>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

using Unisoft.ICS.Utility.Web;
using Unisoft.ICS.Model.CommonEntity;

namespace Unisoft.ICS.Web.UserControls.Common
{
    public partial class GridViewLayout : System.Web.UI.UserControl
    {
        /// <summary>
        /// 当前页唯一的CookieName
        /// </summary>
        private string HttpCookie_Name
        { get { return Security.DESEncrypt("GridViewLayout_ASCX_" + this.ChkGridViewColumnList.ClientID); } }

        /// <summary>
        /// 定义委托
        /// </summary>
        public delegate void EventDelegate();
        /// <summary>
        /// 定义值改变事件
        /// </summary>
        public event EventDelegate SelectedIndexChangedEvent;

        protected void Page_Load(object sender, EventArgs e)
        {
        }

        /// <summary>
        ///从GridView读取所有列信息,并生成绑定到ChkGridViewColumnList控件
        /// </summary>
        /// <param name="_gridview">目标GridView</param>
        public void BindGridViewColumn(GridView _gridview)
        {
            if (_gridview.Rows.Count > 0)
            {
                List<HttpCookies> cookies = new List<HttpCookies>();
                if (Request.Cookies[this.HttpCookie_Name] != null)
                {
                    cookies = JsonHelper.FromJson<List<HttpCookies>>(Request.Cookies[this.HttpCookie_Name].Value);
                }

                this.ChkGridViewColumnList.Items.Clear();
                for (int i = 0; i < _gridview.Columns.Count; i++)
                {
                    if (_gridview.Columns[i].Visible)
                    {
                        ListItem _this = new ListItem(_gridview.Columns[i].HeaderText, i.ToString());

                        //从Cookie中获取配置
                        List<HttpCookies> _cookie = cookies.Where(n => n.HttpCookie_Index == i && n.HttpCookie_Text == _gridview.Columns[i].HeaderText).ToList<HttpCookies>();
                        if (cookies != null && cookies.Count > 0 && _cookie.Count > 0)
                        {
                            _this.Selected = _cookie[0].HttpCookie_Selected;//将Cookie中的配置赋值到CheckBox
                            _gridview.Columns[i].Visible = _this.Selected;//同步GridView列
                        }
                        else
                        {
                            //默认选中
                            _this.Selected = true;
                        }
                        this.ChkGridViewColumnList.Items.Add(_this);
                    }
                }
            }
        }

        /// <summary>
        ///从GridView读取所有列信息,并生成绑定到ChkGridViewColumnList控件
        /// </summary>
        /// <param name="_gridview">目标GridView</param>
        /// <param name="RepeatColumns">单行显示数量:值<0,默认每行14列</param>
        public void BindGridViewColumn(GridView _gridview, int RepeatColumns)
        {
            if (_gridview.Rows.Count > 0)
            {
                if (RepeatColumns > 0)
                { this.ChkGridViewColumnList.RepeatColumns = RepeatColumns; }

                //从Cookie中获取当前页的配置Json,并转换成List<HttpCookies>
                List<HttpCookies> cookies = new List<HttpCookies>();
                if (Request.Cookies[this.HttpCookie_Name] != null)
                { cookies = JsonHelper.FromJson<List<HttpCookies>>(Request.Cookies[this.HttpCookie_Name].Value); }

                //清空CheckBoxList-ListItem
                this.ChkGridViewColumnList.Items.Clear();
                for (int i = 0; i < _gridview.Columns.Count; i++)
                {
                    //GridView可视列
                    if (_gridview.Columns[i].Visible)
                    {
                        //将GridView Column追加到CheckBoxList
                        ListItem _this = new ListItem(_gridview.Columns[i].HeaderText, i.ToString());

                        //从Cookie中获取配置
                        List<HttpCookies> _cookie = cookies.Where(n => n.HttpCookie_Index == i && n.HttpCookie_Text == _gridview.Columns[i].HeaderText).ToList<HttpCookies>();
                        if (cookies != null && cookies.Count > 0 && _cookie.Count > 0)
                        {
                            //将Cookie中的配置赋值到CheckBox
                            _this.Selected = _cookie[0].HttpCookie_Selected;
                            //显示状态同步到GridView列
                            _gridview.Columns[i].Visible = _this.Selected;
                        }
                        else
                        {
                            //默认选中
                            _this.Selected = true;
                        }
                        //将ListItem追加到CheckBoxList中
                        this.ChkGridViewColumnList.Items.Add(_this);
                    }
                }
            }
        }

        /// <summary>
        /// 控制GridView列显示隐藏事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void ChkGridViewColumnList_SelectedIndexChanged(object sender, EventArgs e)
        {
            List<HttpCookies> cookies = new List<HttpCookies>();
            foreach (ListItem item in ChkGridViewColumnList.Items)
            {
                //将CheckBoxList的显示状态写入Cookie中
                HttpCookies _entity = new HttpCookies();
                _entity.HttpCookie_Index = Convert.ToInt32(item.Value);
                _entity.HttpCookie_Text = item.Text;
                _entity.HttpCookie_Selected = item.Selected;
                cookies.Add(_entity);
            }

            //将配置转换成son,并写入Cookie
            HttpCookie cookie = new HttpCookie(HttpCookie_Name, JsonHelper.ToJson<List<HttpCookies>>(cookies));
            cookie.Expires = DateTime.Now.AddMonths(6);//Cookie保存6个月
            Response.Cookies.Add(cookie);

            if (SelectedIndexChangedEvent != null)
            {
                this.SelectedIndexChangedEvent();
            }
        }

        /// <summary>
        /// 更新GridView控件,根据勾选值控制列显示或隐藏
        /// </summary>
        public void ChkGridViewColumnList_UpdateGridViewColumn(GridView _gridview)
        {
            //循环读取CheckBoxList ListItem的显示状态
            foreach (ListItem item in ChkGridViewColumnList.Items)
            {
                //将CheckBoxList ListItem的显示状态,同步到GridView Column
                _gridview.Columns[Convert.ToInt32(item.Value)].Visible = item.Selected;
            }
        }

        /// <summary>
        /// 更新GridView控件,根据勾选值控制列显示或隐藏,并将配置写入Cookie中
        /// </summary>
        public void UpdateGridViewColumn(GridView _gridview)
        {
            foreach (ListItem item in ChkGridViewColumnList.Items)
            {
                _gridview.Columns[Convert.ToInt32(item.Value)].Visible = item.Selected;
            }
        }
    }
}

新增HttpCookies类用于Json序列化

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Unisoft.ICS.Model.CommonEntity
{
    /// <summary>
    /// HttpCookies
    /// </summary>
    public class HttpCookies
    {
        public int HttpCookie_Index;
        public string HttpCookie_Text;
        public bool HttpCookie_Selected;
    }
}
JsonHelper.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Runtime.Serialization.Json;
using Newtonsoft.Json;
using System.Data;
using System.Web.Script.Serialization;
using System.Text.RegularExpressions;

namespace Unisoft.ICS.Utility.Web
{
    public static class JsonHelper
    {
        private readonly static JavaScriptSerializer jsonSerializer = new JavaScriptSerializer();

        /// <summary>
        /// 生成Json格式
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static string GetJson<T>(T obj)
        {

            DataContractJsonSerializer json = new DataContractJsonSerializer(obj.GetType());
            using (MemoryStream stream = new MemoryStream())
            {
                json.WriteObject(stream, obj);
                string szJson = Encoding.UTF8.GetString(stream.ToArray()); return szJson;
            }
        }
        /// <summary>
        /// 获取Json的Model
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="szJson"></param>
        /// <returns></returns>
        public static T ParseFromJson<T>(string szJson)
        {
            T obj = Activator.CreateInstance<T>();
            using (MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(szJson)))
            {
                DataContractJsonSerializer serializer = new DataContractJsonSerializer(obj.GetType());
                return (T)serializer.ReadObject(ms);
            }
        }
        public static string DataTableToJSON(DataTable dt, string dtName)
        {
            StringBuilder sb = new StringBuilder();
            StringWriter sw = new StringWriter(sb);

            using (JsonWriter jw = new JsonTextWriter(sw))
            {
                JsonSerializer ser = new JsonSerializer();
                jw.WriteStartObject();
                jw.WritePropertyName(dtName);
                jw.WriteStartArray();
                foreach (DataRow dr in dt.Rows)
                {
                    jw.WriteStartObject();

                    foreach (DataColumn dc in dt.Columns)
                    {
                        jw.WritePropertyName(dc.ColumnName);
                        ser.Serialize(jw, dr[dc].ToString());
                    }

                    jw.WriteEndObject();
                }
                jw.WriteEndArray();
                jw.WriteEndObject();

                sw.Close();
                jw.Close();

            }

            return sb.ToString();
        }

        /// <summary>
        /// 将 T 对象转为 Json 字符串
        /// </summary>
        /// <param name="jsonObj"></param>
        /// <returns></returns>
        public static string ToJson<T>(T jsonObj)
        {
            var _jsonstring = jsonSerializer.Serialize(jsonObj);
            var _regex = new Regex(@"\\/Date\((?<date>\d+)\)\\/");
            var _match = _regex.Match(_jsonstring);
            int _add = 0;
            while (_match.Success)
            {
                var _tmp = _jsonstring.Remove(_match.Index + _add, _match.Length);
                var _mid = "new Date(" + _match.Groups["date"] + ")";
                _jsonstring = _tmp.Insert(_match.Index + _add, _mid);
                _add += _mid.Length - _match.Length;
                _match = _match.NextMatch();
            }
            return _jsonstring;
        }

        /// <summary>
        /// 将 Json 字符串转为 Json 对象
        /// </summary>
        /// <param name="jsonString"></param>
        /// <returns></returns>
        public static T FromJson<T>(string jsonString)
        {
            return jsonSerializer.Deserialize<T>(jsonString);
        }

        #region DataTable序列化json
        /// <summary> 
        /// DataTable转为json 
        /// </summary> 
        /// <param name="dt">DataTable</param> 
        /// <returns>json数据</returns> 
        public static string DataTableToJson(DataTable dt)
        {
            List<Dictionary<string, object>> list = new List<Dictionary<string, object>>();
            foreach (DataRow dr in dt.Rows)
            {
                Dictionary<string, object> result = new Dictionary<string, object>();
                foreach (DataColumn dc in dt.Columns)
                {
                    result.Add(dc.ColumnName, dr[dc]);
                }
                list.Add(result);
            }

            return SerializeDataTableToJson(list);
        }

        /// <summary>
        /// 序列化对象为Json字符串
        /// </summary>
        /// <param name="obj">要序列化的对象</param>
        /// <param name="recursionLimit">序列化对象的深度,默认为100</param>
        /// <returns>Json字符串</returns>
        public static string SerializeDataTableToJson(this object obj)
        {
            JavaScriptSerializer serialize = new JavaScriptSerializer();
            serialize.RecursionLimit = 100;
            return serialize.Serialize(obj);
        }
        #endregion

    }
}

引用代码

<%@ Register src="../../UserControls/Common/GridViewLayout.ascx" tagname="GridViewLayout" tagprefix="uc" %>
<uc:GridViewLayout ID="ucGridViewLayout" runat="server" />

<asp:UpdatePanel ID="uppPanel" runat="server" UpdateMode="Conditional">
    <ContentTemplate>
                <asp:GridView ID="GridView" runat="server">
                    <EmptyDataTemplate>
                        <span class="noRecord">没有记录!</span>
                    </EmptyDataTemplate>
                </asp:GridView>
            </div>
        </asp:Panel>
    </ContentTemplate>
</asp:UpdatePanel>
protected void Page_Load(object sender, EventArgs e)
{    //实现控件委托
     this.ucGridViewLayout.SelectedIndexChangedEvent += new Unisoft.ICS.Web.UserControls.Common.GridViewLayout.EventDelegate(ucGridViewLayout_SelectedIndexChangedEvent);
     if (!Page.IsPostBack)
     {

        //绑定GridView业务代码

this.BindProductList(); 
//初始化用户控件 this.ucGridViewLayout.BindGridViewColumn(GridView);//传入GridView ID 
}
}

//绑定GridView业务代码

protected void BindProductList(){this.gvProductList.DataSource = 数据源;this.gvProductList.DataBind(); 

    this.ucGridViewLayout.UpdateGridViewColumn(this.gvProductList);

}

 //控件回调执行更新列
void ucGridViewLayout_SelectedIndexChangedEvent()
{
     this.ucGridViewLayout.UpdateGridViewColumn(this.gvProductList);
     this.uppPanel.Update();
}

    <asp:UpdatePanel ID="uppPanel" runat="server" UpdateMode="Conditional">
        <ContentTemplate>
                    <asp:GridView ID="GridView" runat="server">
                        <EmptyDataTemplate>
                            <span class="noRecord">没有记录!</span>
                        </EmptyDataTemplate>
                    </asp:GridView>
                </div>
            </asp:Panel>
        </ContentTemplate>
    </asp:UpdatePanel>

 /// <summary>
/// 导出
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void lbtnOutput_Click(object sender, EventArgs e)
{
    IsOutput = true;
    this.BindProductList();
    this.ucGridViewLayout.UpdateGridViewColumn(this.gvProductList);
    ToExcel(this.Panel1, "库存台账" + DateTime.Now.ToString("yyyy-MM-dd"));
}

/// <summary>
/// 导出到EXCEL
/// </summary>
/// <param name="ctl"></param>
/// <param name="FileName"></param>
public void ToExcel(System.Web.UI.Control ctl, string FileName)
{
    //火狐浏览器下导出Excel文件时,文件名转码,可防止中文出现乱码(其它浏览器转码反而会乱码)
    if (!string.IsNullOrEmpty(FileName) && !(HttpContext.Current.Request.UserAgent != null && HttpContext.Current.Request.UserAgent.ToUpper().IndexOf("FIREFOX", StringComparison.Ordinal) != -1))
    { FileName = System.Web.HttpUtility.UrlEncode(FileName, System.Text.Encoding.UTF8); }
    HttpContext.Current.Response.Charset = "UTF-8"; // 或UTF-7 以防乱码
    HttpContext.Current.Response.ContentEncoding = System.Text.Encoding.UTF8;
    HttpContext.Current.Response.ContentType = "application/vnd.ms-excel";
    HttpContext.Current.Response.AppendHeader("Content-Disposition", "attachment;filename=" + FileName + ".xls");
    ctl.Page.EnableViewState = false;
    System.IO.StringWriter tw = new System.IO.StringWriter();
    System.Web.UI.HtmlTextWriter hw = new System.Web.UI.HtmlTextWriter(tw);
    ctl.RenderControl(hw);
    HttpContext.Current.Response.Write(tw.ToString());
    HttpContext.Current.Response.End();
    ctl.Page.EnableViewState = false;
}
ASP.NET实现Gridview隐藏/显示源码 介绍: 这篇文章演示如果让用户显示/隐藏他们需要的GridView的功能,这是非常有用的,因为在GridView的所有并不是每个的用户都需要的.用户想根据自己的需求看到想要的.而不是显示一个巨大的gridview,霸占了整个屏幕,而是一个整洁的Gridview,而且它有所有你需要的.对于页面的打印这也是一个非常有用的技术,因为用户可以灵活地选择GridView打印。 背景: RowCreated 和ItemDataBound 事件允许你用多种方式注入HTML, CSS,和JavaScript 来增强GridView 控件的功能。 文章将会演示两种显示隐藏GridView的方法,一种是客户端的方法,另外一种是服务段的方法. 在客户显示隐藏GridView 大部分代码是在GridView的RowCreated事件生成客户端的功能的。当GridView的Header行被创建后,一个带负号的HyperLink被插入每个Header行的单元格中用来隐藏。 这个hyperlink通过它的onclick事件调用一个HideCol的Javascript方法,CSS类用来增加负号的大小,当每个数据行被创建的时候,一个Id将会被添加到每行中用来让Javascript区分每一行. 代码 protected void GridView1_RowCreated(object sender, GridViewRowEventArgs e) { GridView gridView = (GridView)sender; StringBuilder sb = new StringBuilder(); // For the header row add a link to each header // cell which can call the HideCol javascript method if (e.Row.RowType == DataControlRowType.Header) { // Loop through each cell of the row for (int columnIndex = 0; columnIndex 0) { Label columnTextLabel = new Label(); columnTextLabel.Text = e.Row.Cells[columnIndex].Text; e.Row.Cells[columnIndex].Controls.Add(columnTextLabel); } } } // Give each row an id if (e.Row.RowType == DataControlRowType.Pager) e.Row.Attributes.Add("id", gridView.ClientID + "_pager"); else e.Row.Attributes.Add("id", gridView.ClientID + "_r" + e.Row.RowIndex.ToString()); } SetupShowHideColumns方法中生成“Show Columns”下拉菜单的HTML,输出在Literal控件上面 。 代码 private void SetupShowHideColumns(GridView gridView, Literal showHideColumnsLiteral) { StringBuilder sb = new StringBuilder(); sb.Append(""); sb.Append(""); sb.Append("- Show Column -"); showHideColumnsLiteral.Text = sb.ToString(); } 在数据绑定到GridView之后,其余的工作由ShowHideColumns.js中的javascript来完成.当头的hyperlink被点击的时候后,它将会传递GridView的名字,的索引和名给HideCol方法,这个方法能找到这一的每个单元格,每个单元格的将添加display:none样式,用来隐藏这一. 当选择"Show Column"中的选项后,Javascript方法ShowCol将会被调用,它将移除每个单元格的display:none样式,这一将会被再次显示. 在服务端显示/隐藏GridView 服务端的例子将通过RowCreated事件给每个头添加一个负号,这次是使用LinkButton控件.设置CommandName和CommandArgument属性,这样当通过LinkButton引发RowCommand事件时,相关的都可以隐藏。以前隐藏索引存储在一个List中,这些在建立时,将会被隐藏的。 代码 protected void GridView1_RowCreated(object sender, GridViewRowEventArgs e) { // For the header row add a link button to each header // cell which can execute a row command if (e.Row.RowType == DataControlRowType.Header) { // Loop through each cell of the header row for (int columnIndex = 0; columnIndex 0) { Label columnTextLabel = new Label(); columnTextLabel.Text = e.Row.Cells[columnIndex].Text; e.Row.Cells[columnIndex].Controls.Add(columnTextLabel); } } } // Hide the column indexes which have been stored in hiddenColumnIndexes foreach(int columnIndex in hiddenColumnIndexes) if (columnIndex 0) { this.GridView1ShowHideColumns.Visible = true; this.GridView1ShowHideColumns.Items.Add(new ListItem("-Show Column-", "-1")); foreach (int i in hiddenColumnIndexes) this.GridView1ShowHideColumns.Items.Add( new ListItem(columnNames[i], i.ToString())); } else { this.GridView1ShowHideColumns.Visible = false; } } 示例项目的例子: 客户端的例子: •C#.NET - Client-side example accessing data stored in session. •C#.NET - Client-side example which includes: MasterPage, UpdatePanel, GridView editing, paging and sorting, accessing data via the SqlDataSource control. •VB.NET - Client-side example accessing data stored in session. 服务端的例子 •C#.NET - Server-side example accessing data stored in session. •C#.NET - Server-side example which includes: MasterPage, UpdatePanel, GridView editing, paging and sorting, accessing data via the SqlDataSource control. •VB.NET - Server-side example accessing data stored in session. 结论: 如果你想让你的用户能够显示隐藏ASP.NET GridView,那么这种技术可能是非常有用的。 原文:http://www.codeproject.com/KB/webforms/ShowHideGridviewColumns.aspx 作者:朱祁林 出处:http://zhuqil.cnblogs.com/ 本文权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值