• 扩展GridView控件增加选择列


    效果演示地址:http://demo.yuefan.net/

    GridView是asp.net 2.0中,最常用、最好用的服务器控件之一;但是,为了让它更适应于我们具体的项目,我们很多时候,需要对它进行一些特殊操作。

    如,实现如下效果(如果下图看不到,可以到我的百度空间看:扩展GridView控件--增加选择列)

    当然,我承认,实现如上效果并不复杂,
    1、增加一个模版列放置复选框;
    2、合并底部(footer)并放置三个LinkButton,即全选、反选、取消;并写相应事件,使其可以操作各行中的复选框;
    3、然后在OnRowDataBound事件中,给各个行加上JavaScript事件,使各个数据行可以响应鼠标悬停,以及单击事件;
    4、当能过其它的操作(如点击删除按钮)来操作数据行时,用foreach遍历各数据行即可;

    问题是,我们的项目中,会非常频繁的用到这个效果,作一个懒人,每次要拷贝代码,实在是太麻烦了。写一个增强的GridView控件,才是明智之举;

    如上效果所示,这个增强GridView应该具备以下功能:
    1、拖上来就能用,自带一个选择列;这个选择列要能够绑定数据(可选);也就是说,增强控件只能比以前更方便,不能更复杂。
    2、footer自动合并,并带三个LinkButton;对复选框操作采用JavaScript方法,在客户端执行,这样无须刷新页面,操作更流畅;
    3、能够自动取出选中的行,不必再foreach遍历;
    4、带一些参数,可以选择是否显示“选择列”,以及取选中行的主键值;

    为了实现以上效果,要写C#,也要写JavaScript与Css;

    例如,动态增加模版列,当然得写C#代码操作;利用控件的OnInit事件;
    而数据行的鼠标悬停与单击,当然得写JavaScript,用它来操作加载Css样式;这里我用了Jquery框架。

    我在这里把主要的C#代码拿出来供学习吧。关键的地方我做了描述,当然,里面有一些代码写得有冗余,也是自己懒,不想在客户端做太多判断,直接标识了数据行,如e.Row.Attributes.Add("RowType","DataRow");,之类的,都是为方便js在客户端判断。

    代码如下:

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Text;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using System.Web.UI.HtmlControls;

    namespace Company.CustomControl
    {
        [DefaultProperty("Text")]
        [ToolboxData("<{0}:GridView runat=server></{0}:GridView>")]

        public class GridView : System.Web.UI.WebControls.GridView
        {
            #region 属性
            [Bindable(true)]
            [Category("Appearance")]
            [DefaultValue("用于选择的复选框所在数据列的,数据列名称,即绑定值")]
            [Localizable(true)]
            public string SelectBoxKeyName
            {
                get
                {
                    String s = (String)ViewState["SelectBoxKeyName"];
                    return ((s == null) ? "SelectBox" : s);
                }

                set
                {
                    ViewState["SelectBoxKeyName"] = value;
                }
            }
            [Bindable(true)]
            [Category("Appearance")]
            [DefaultValue("是否显示用于选择的复选框的数据列")]
            [Localizable(true)]
            public bool ShowSelectBox
            {
                get
                {
                    String s = (String)ViewState["ShowSelectBox"];
                    return Convert.ToBoolean(((s == null) ? "True" : s));
                }

                set
                {
                    ViewState["ShowSelectBox"] = value.ToString();
                }
            }
            /// <summary>
            /// 获取选中数据行的主键值
            /// </summary>
            [Bindable(true)]
            [DefaultValue(" 获取选中数据行的主键值")]
            [Localizable(true)]
            [Category("Appearance")]
            public string GetKeyValues
            {
                get
                {
                    if (this.DataKeyNames.Length < 1)
                    {
                        return "";
                    }
                    string tmp = "";
                    foreach (GridViewRow vr in this.Rows)
                    {
                        if (vr.RowType == DataControlRowType.DataRow)
                        {
                            CheckBox cb = (CheckBox)vr.FindControl(this.SelectBoxKeyName);
                            if (cb.Checked)
                            {
                                tmp += this.DataKeys[vr.RowIndex].Value.ToString() + ",";
                            }
                        }
                    }
                    if (tmp.IndexOf(",") > -1)
                    {
                        tmp = tmp.Substring(0, tmp.LastIndexOf(","));
                    }
                    return tmp;
                }
            }
            #endregion
           
            protected override void OnDataBound(EventArgs e)
            {
                if (this.CssClass == String.Empty)
                {
                    this.CssClass = "GridView";
                }
                base.OnDataBound(e);
            }
           
            protected override void OnInit(EventArgs e)
            {
                //绑定选择框的列
                if (this.ShowSelectBox)
                {
                    TemplateField dcf = new TemplateField();
                    dcf.HeaderText = "选择";

                    CheckTemplate mt = new CheckTemplate(this.SelectBoxKeyName);
                    dcf.ItemTemplate = mt;
                    this.Columns.Insert(0, dcf);
                }
                base.OnInit(e);
               
            }

            protected override void OnRowDataBound(GridViewRowEventArgs e)
            {
                //当为数据行时
                if (e.Row.RowType == DataControlRowType.DataRow)
                {
                    e.Row.Attributes.Add("RowType","DataRow");
                    //取主键的值
                    if (this.DataKeyNames != null && this.DataKeyNames.Length>0)
                    {
                        string val = this.DataKeys[e.Row.RowIndex].Value.ToString();
                        e.Row.Attributes.Add("DataKey", val);
                    }
                    e.Row.Cells[0].Attributes.Add("ItemType","SelectBox");
                }
                //底部栏的跨列
                if (e.Row.RowType == DataControlRowType.Footer)
                {
                    e.Row.Attributes.Add("RowType", "Footer");
                    int col = e.Row.Cells.Count;
                    e.Row.Cells[0].ColumnSpan = col;
                    while (--col > 0)
                    {
                        e.Row.Cells[col].Visible = false;
                    }
                    e.Row.Cells[0].Attributes.Add("ItemType", "SelectHandler");
                    e.Row.Cells[0].Text = "全选、反选、取消";
                }
               
                base.OnRowDataBound(e);
            }       

        }
        /// <summary>
        /// 用于载入复选框的类,该类很重要,是用于自定义GridView模版列的必然方法;
        /// </summary>
        public class CheckTemplate : ITemplate
        {
            private string colname;
            public CheckTemplate(string colname)
            {
                this.colname = colname;
            }

            public void InstantiateIn(Control container)
            {
                CheckBox cb = new CheckBox();
                cb.ID = colname;
                cb.CssClass = colname;
                cb.Attributes.Add("ControlType", "SelectBox");

                cb.DataBinding += new EventHandler(this.OnDataBinding);
                container.Controls.Add(cb);
            }

            public void OnDataBinding(object sender, EventArgs e)
            {           
                try
                {
                    //用于数据绑定
                    CheckBox cb = (CheckBox)sender;
                    GridViewRow container = (GridViewRow)cb.NamingContainer;
                    //如果存在该数据列,则绑定;
                    cb.Checked = Convert.ToBoolean(((DataRowView)container.DataItem)[colname].ToString());
                }
                catch
                {
                      //我不是有意要写try,只是当SelectBoxKeyName属性为空时,即用户并不想给选择列绑定数据时,这里不至于出错;
                     //如果SelectBoxKeyName属性不为空,其数据会自动绑定到选择列上。
                }
               
            }
        }

    }

    上面的控件,增加了三个属性;
    SelectBoxKeyName:这个是对选择列进行数据绑定时的键值,如DataTable的列名;这个可以不填的。
    ShowSelectBox:是否显示的选择列,默认为显示;
    GetKeyValues:获取选中数据行的主键值;如果没有主键,或没有选中行,则返回空字符,否则返回主键列表字符串,用逗号分隔;如10,20,55,56;

    使用很简单,asp.net页面中代码如下
    <%@ Register Assembly="Company.CustomControl" Namespace="Company.CustomControl" TagPrefix="cc1" %>
    <cc1:GridView ID="GridView1" runat="server" ShowFooter="True">
            </cc1:GridView>

    绑定数据后,就显示出如顶部图中的效果。

    我抽空把它整理出来,单独放到一个项目中,做个完整示例,发上来吧。以上代码,供参考学习;

    完整示例做好了(vs2005 sp1):
    GridViewDemo.rar

  • 相关阅读:
    C++多线程基础学习笔记(三)
    js 实现排序算法 -- 快速排序(Quick Sort)
    js 实现排序算法 -- 归并排序(Merge Sort)
    Typescript
    Typescript
    Typescript
    Typescript
    Typescript
    Typescript
    js 实现排序算法 -- 希尔排序(Shell Sort)
  • 原文地址:https://www.cnblogs.com/2hill/p/1351929.html
Copyright © 2020-2023  润新知