重新封装了一个 GridView,支持如下功能:
1. CheckBox选择记录,指定CheckBox的位置
2. 支持List,DataSet,Datatable 排序
3. 排序时在Header部分出现图标
4. 封装了PageIndexChanged 和DataBind,不用每页都写。
5. 支持SQL分页和ApsNetPager等分页控件。
注: 没有加入很多的功能,因为本身需要的就是一个轻量级的GridView,产生近可能少的代码。
另:选择高亮功能是用JQuery实现的,因此使用时需要JQuery的运行库。
代码1 : 辅助对象,实现Sort排序。(其实这部分功能可以用LINQ来做,会简单很多,当这个类已经用了很久了,懒得改了)
1 using System;
2 using System.Collections;
3 using System.Collections.Generic;
4 using System.Reflection;
5
6 namespace xxWare.xxControls
7 {
8 public class Reverser<T> : IComparer<T>
9 {
10 private Type _type = null;
11 private ReverserInfo info;
12
13 /// <summary>
14 /// 构造函数
15 /// </summary>
16 /// <param name="type">进行比较的类类型</param>
17 /// <param name="name">进行比较对象的属性名称</param>
18 /// <param name="direction">比较方向(升序/降序)</param>
19 public Reverser(Type _type, string _name, string _direction)
20 {
21 this._type = _type;
22 this.info.name = _name;
23 this.info.direction = _direction.ToLower();
24 }
25
26 /// <summary>
27 /// 构造函数
28 /// </summary>
29 /// <param name="className">进行比较的类名称</param>
30 /// <param name="name">进行比较对象的属性名称</param>
31 /// <param name="direction">比较方向(升序/降序)</param>
32 public Reverser(string _className, string _name, string _direction)
33 {
34 try
35 {
36 this._type = Type.GetType(_className, true);
37 this.info.name = _name;
38 this.info.direction = _direction.ToLower();
39 }
40 catch (Exception e)
41 {
42 throw new Exception(e.Message);
43 }
44
45 }
46
47 /// <summary>
48 /// 构造函数
49 /// </summary>
50 /// <param name="t">进行比较的类型的实例</param>
51 /// <param name="name">进行比较对象的属性名称</param>
52 /// <param name="direction">比较方向(升序/降序)</param>
53 public Reverser(T _t, string _name, string _direction)
54 {
55 this._type = _t.GetType();
56 this.info.name = _name;
57 this.info.direction = _direction;
58 }
59
60 int IComparer<T>.Compare(T t1, T t2)
61 {
62 object x = this._type.InvokeMember(this.info.name, BindingFlags.Public | BindingFlags.Instance | BindingFlags.GetProperty, null, t1, null);
63 object y = this._type.InvokeMember(this.info.name, BindingFlags.Public | BindingFlags.Instance | BindingFlags.GetProperty, null, t2, null);
64
65 if (this.info.direction != "asc")
66 Swap(ref x, ref y);
67 return (new CaseInsensitiveComparer()).Compare(x, y);
68 }
69
70 void Swap(ref object x, ref object y)
71 {
72 object tmp = x;
73 x = y;
74 y = tmp;
75 }
76 }
77 public struct ReverserInfo
78 {
79 public enum Target
80 {
81 Customer = 0,
82 From,
83 Field,
84 Server
85 }
86
87 public string name;
88 public string direction; // asc , desc ;
89 public Target target;
90 }
91 }
代码2: Template类,用于生成CheckBox列
1 using System;
2 using System.Web;
3 using System.Web.UI;
4 using System.Web.UI.WebControls;
5
6 namespace xxWare.xxControls
7 {
8 #region Selector Template
9 public class xxGridColumnTemplate : ITemplate
10 {
11 public void InstantiateIn(Control container)
12 {
13 CheckBox cb = new CheckBox();
14 cb.ID = "FarGV_ColumnSelector";
15 cb.ClientIDMode = ClientIDMode.AutoID;
16 cb.CssClass = "far_rowsselector";
17 container.Controls.AddAt(0, cb);
18 }
19 }
20
21 public class xxGridHeaderTemplate : ITemplate
22 {
23 public void InstantiateIn(Control container)
24 {
25 System.Web.UI.HtmlControls.HtmlInputCheckBox selectAll = new System.Web.UI.HtmlControls.HtmlInputCheckBox();
26 selectAll.ID = "FarGV_ColumnSelectorAll";
27 selectAll.ClientIDMode = ClientIDMode.Static;
28 selectAll.Attributes["onclick"] = "FarGridView_ColumnSelectorAll();";
29 container.Controls.Add(selectAll);
30 }
31 }
32
33 #endregion
34
35 }
主代码: 加了一个属性 AutoSort,当使用SQL分页是,设置为 False即可
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; using System.Reflection; namespace xxWare.xxControls { [ToolboxData("<{0}:xxGridView runat=server></{0}:xxGridView>")] public class xxGridView : System.Web.UI.WebControls.GridView { #region Properties // sort image url : full url = Sort_Image_Url + Asc_Image_Name [Browsable(true) , Category("Sort Image"), DefaultValue("images/arrow_up.gif") , Description("Asc Image")] public string Asc_Image { get; set; } [Browsable(true), Category("Sort Image"), DefaultValue("images/arrow_down.gif"), Description("Desc Image")] public string Desc_Image { get; set; } [Browsable(true), Category("Sort Image"), DefaultValue("images/arrow_updn.gif"), Description("Sortable Image")] public string Sort_Image { get; set; } //Property : SortExpression [Browsable(false)] public string CurrentSortExpression { get { return Convert.ToString(ViewState["CurrentSortExpression"]); } set { ViewState["CurrentSortExpression"] = value.Trim(); } } [Browsable(false)] public string CurrentSortDirection { get { return Convert.ToString(ViewState["CurrentSortDirection"]); } set { if (string.IsNullOrEmpty(value)) { ViewState["CurrentSortDirection"] = "desc"; } else { if (value.ToLower() != "asc" && value.ToLower() != "desc") { ViewState["CurrentSortDirection"] = "desc"; } else { ViewState["CurrentSortDirection"] = value.ToString().ToLower(); } } } } //Property : Multi Show CheckBox [Category("MultiSelect") , DefaultValue("True")] public bool AllowMultiSelect { get { return bool.Parse(ViewState["AllowMultiSelect"].ToString()); } set { ViewState["AllowMultiSelect"] = value.ToString(); } } [Category("MultiSelect"), DefaultValue(0)] public int AllowMultiSelectColumn { get { return Int32.Parse(ViewState["AllowMultiSelectColumn"].ToString()); } set { ViewState["AllowMultiSelectColumn"] = value.ToString(); } } /* public string RowSelectFilter { get { return (string)ViewState["RowSelectFilter"]; } set { ViewState["RowSelectFilter"] = value.ToString(); } } * */ //Property : Get Selected Items [Browsable(false)] public List<GridViewRow> MultiSelectedItem { get { if (!AllowMultiSelect) return null; List<GridViewRow> selectedRows = new List<GridViewRow>(); foreach (GridViewRow row in this.Rows) { CheckBox cb = (CheckBox)row.Cells[AllowMultiSelectColumn].Controls[0]; if (cb.Checked) { selectedRows.Add(row); } } return selectedRows; } } //Define DataSource private object sourcedata; public object DataSetSource { get { if (sourcedata != null) return sourcedata; else return null; } set { sourcedata = value as object; } } //record count: readonly private int _recordCount = 0; [Browsable(false)] public int RecordCount { get { return _recordCount; } } //AutoSort : True/False , set to False when use 3rd pager control and Sql Pager , e.g. AspNetPager, DataPager ... [Browsable(true), Category("Misc"), DefaultValue("True"), Description("Auto Pager")] public bool AutoSort { get; set; } #endregion private ClientScriptManager csManager; public xxGridView() : base() { AllowPaging = false; AllowSorting = true; AutoSort = false; //GridLines = GridLines.Horizontal; //BorderWidth = (Unit)0; // Sort Images Default Asc_Image = @"images/arrow_up.gif"; Desc_Image = @"images/arrow_down.gif"; Sort_Image = @"images/arrow_updn.gif"; //set event handlers Init += new EventHandler(On_Init); Sorting += new GridViewSortEventHandler(On_Sorting); RowCreated += new GridViewRowEventHandler(On_RowCreated); } #region Event Handlers public event EventHandler GridBindEvent; public virtual void OnGridBind<T>() { if (sourcedata!=null) { if (CurrentSortExpression==string.Empty) { this.DataSource = sourcedata; this.DataBind(); return; } //Datasource Type if (sourcedata is DataTable) { DataView dv = (sourcedata as DataTable).DefaultView; if (!string.IsNullOrEmpty(CurrentSortExpression) && AutoSort) dv.Sort = CurrentSortExpression + " " + CurrentSortDirection; this.DataSource = dv; _recordCount = dv.Count; try { this.DataBind(); } catch { if (this.PageIndex>1) { this.PageIndex--; this.DataBind(); } } } else if (sourcedata is DataSet) { DataView dv = (sourcedata as DataSet).Tables[0].DefaultView; if (!string.IsNullOrEmpty(CurrentSortExpression) && AutoSort) dv.Sort = CurrentSortExpression + " " + CurrentSortDirection; this.DataSource = dv; _recordCount = dv.Count; try { this.DataBind(); } catch { if (this.PageIndex > 1) { this.PageIndex--; this.DataBind(); } } } else if (sourcedata is List<T>) { if (!string.IsNullOrEmpty(CurrentSortExpression) && AutoSort) { Reverser<T> reverser = new Reverser<T>(typeof(T), CurrentSortExpression, CurrentSortDirection); (sourcedata as List<T>).Sort(reverser); } this.DataSource = sourcedata; _recordCount = (sourcedata as List<T>).Count; try { this.DataBind(); } catch { if (this.PageIndex > 1) { this.PageIndex--; this.DataBind(); } } } } } public void On_Init(object sender, EventArgs e) { // processing multi-select if (ViewState["AllowMultiSelect"]==null || ViewState["AllowMultiSelect"].ToString().Trim()=="") ViewState["AllowMultiSelect"] = "True"; if (ViewState["AllowMultiSelectColumn"] == null || ViewState["AllowMultiSelectColumn"].ToString().Trim() == "") ViewState["AllowMultiSelectColumn"] = "0"; csManager = this.Page.ClientScript; if (AllowMultiSelect) { AddSelectColumn(); RegisterJS(); } // processing sorting... if (CurrentSortDirection == null || CurrentSortDirection.Trim() == "") CurrentSortDirection = "desc"; if (CurrentSortExpression == null) CurrentSortDirection = ""; } public void On_Sorting(object sender , GridViewSortEventArgs e) { CurrentSortExpression = e.SortExpression; if (CurrentSortDirection == "desc") CurrentSortDirection = "asc"; else CurrentSortDirection = "desc"; GridBindEvent(this , EventArgs.Empty); } public void On_RowCreated(object sender , GridViewRowEventArgs e) { string currentSortImage = ""; if (e.Row.RowType==DataControlRowType.Header) { foreach (DataControlField field in this.Columns) { if (!String.IsNullOrEmpty(field.SortExpression)) { if (IsSortedByThisField(field.SortExpression)) { currentSortImage = (CurrentSortDirection == "asc") ? Asc_Image : Desc_Image; } else { currentSortImage = Sort_Image; } AddSortImage(e.Row, this.Columns.IndexOf(field), currentSortImage); } } } } #endregion #region Override Methods protected override void OnPageIndexChanging(GridViewPageEventArgs e) { //base.OnPageIndexChanging(e); this.PageIndex = e.NewPageIndex; GridBindEvent(this, EventArgs.Empty); } #endregion #region private helper function // For Sort private void AddSortImage(GridViewRow _row, int _colIndex ,string _currImage) { if (-1 == _colIndex) return; Image sortImage = new Image(); sortImage.ImageUrl = _currImage; _row.Cells[_colIndex].Controls.AddAt(1, sortImage); } private bool IsSortedByThisField(String strSortExpression) { return CurrentSortExpression.ToLower() == strSortExpression.Trim().ToLower(); } // for Multi Select private void AddSelectColumn() { TemplateField tc = new TemplateField(); tc.ItemTemplate = new xxGridColumnTemplate(); tc.HeaderTemplate = new xxGridHeaderTemplate(); this.Columns.Insert(AllowMultiSelectColumn, tc); } private void RegisterJS() { /* System.Resources.ResourceManager rm = new System.Resources.ResourceManager("FarGridView", Assembly.GetExecutingAssembly()); string _script = rm.GetString("js_selectall"); if (!csManager.IsClientScriptBlockRegistered(this.GetType() , "js_selectall")) { csManager.RegisterClientScriptBlock(this.GetType(), "js_selectall", _script); } */ csManager.RegisterClientScriptResource(this.GetType(), "xxWare.xxControls.xxGridViewJS.js"); } #endregion } }特别说明:有人问我这个控件的版权问题,这个东东是俺自己做的,没有版权问题,你想怎么改就怎么改,如果你在修改的时候,有一个好主意或者功能,一定要告诉俺