重写GridView支持数据筛选和自动排序功能

控件使用方法:

1.在页面Page_Load()方法的!Page.IsPostBack外面重新绑定数据源,即为DataSource赋值,因为页面回传时!Page.IsPostBack内的方法不会执行,先前赋值的DataSource为null。

2.将AllowSelecting属性设置为true

3.将AllowSorting属性设置为true,并为SortExpression赋值

筛选数据前图:

c1

回车,筛选数据后图:

c2

实现代码如下:

  1 using System;
2 using System.Collections.Generic;
3 using System.ComponentModel;
4 using System.Text;
5 using System.Web;
6 using System.Web.UI;
7 using System.Web.UI.WebControls;
8 using System.Collections;
9 using System.Data;
10 using System.Reflection;
11 using System.Drawing.Design;
12
13 namespace WebCustomControls
14 {
15 public class SupperGridView : System.Web.UI.WebControls.GridView
16 {
17 private Dictionary<string, string> dic = new Dictionary<string, string>();
18 private GridViewRow selectorRow;
19
20 public SupperGridView()
21 : base()
22 { }
23
24 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden),Browsable(false)]
25 public GridViewRow SelectorRow
26 {
27 get
28 {
29 if (selectorRow == null)
30 {
31 this.EnsureChildControls();
32 }
33 return this.selectorRow;
34 }
35 }
36
37 [DefaultValue(false)]
38 public bool AllowSelecting
39 {
40 get
41 {
42 object o = ViewState["Selecting"];
43
44 if (o != null)
45 {
46 return (bool)o;
47 }
48 return false;
49 }
50 set
51 {
52 ViewState["Selecting"] = value;
53 }
54 }
55
56 protected override int CreateChildControls(System.Collections.IEnumerable dataSource, bool dataBinding)
57 {
58 int num= base.CreateChildControls(dataSource, dataBinding);
59
60 if (dataSource != null && AllowSelecting)
61 {
62 CreateSelectedRow();
63 }
64
65 return num;
66 }
67
68 // 创建数据筛选行
69 protected virtual void CreateSelectedRow()
70 {
71 if (this.Controls.Count != 0)
72 {
73 dic.Clear();
74 Table table = (Table)this.Controls[0];
75 TableRowCollection rows = table.Rows;
76 selectorRow = CreateRow(0, 0, DataControlRowType.Header, DataControlRowState.Normal);
77 selectorRow.ID = "SelectRow";
78 TableCellCollection cells = selectorRow.Cells;
79
80 for (int i = 0; i < Columns.Count; i++)
81 {
82 TableCell cell = new TableCell();
83 TextBox box = new TextBox();
84 box.ID = "box" + i;
85 box.BorderStyle = BorderStyle.None;
86 box.AutoPostBack = true;
87 box.TextChanged += new EventHandler(box_TextChanged);
88
89 cell.Controls.Add(box);
90 cells.AddAt(i, cell);
91 dic.Add(box.ID, Columns[i].HeaderText);
92 }
93 rows.AddAt(1, selectorRow);
94 }
95 }
96
97 private void box_TextChanged(object sender, EventArgs e)
98 {
99 if (DataSource == null) return;
100
101 TextBox box = (TextBox)sender;
102 DataTable table = SelectDataFromTextBox(box);
103
104 if (table.Rows.Count == 0)
105 {
106 Page.ClientScript.RegisterClientScriptBlock(this.GetType(), this.GetType().FullName, "alert('对不起,没有您搜索的记录!')", true);
107 return;
108 }
109
110 DataSource = table;
111 DataBind();
112 }
113
114 //筛选数据逻辑,用linq实现可能给方便
115 protected virtual DataTable SelectDataFromTextBox(TextBox box)
116 {
117 DataTable oldTable = ConvertToDataTable(GetData());
118 DataTable newTable = oldTable.Clone();
119 DataRow[] rows = null;
120 Type columnDataType = oldTable.Columns[dic[box.ID]].DataType;
121
122 // Column.DataType是string类型
123 if (columnDataType == typeof(string))
124 {
125 rows = oldTable.Select("" + dic[box.ID] + " like '%" + box.Text + "%'");
126 }
127 // Column.DataType非string类型
128 else
129 {
130 rows = oldTable.Select("" + dic[box.ID] + "='" + box.Text + "'");
131 }
132
133 foreach (DataRow row in rows)
134 {
135 newTable.Rows.Add(row.ItemArray);
136 }
137 return newTable;
138 }
139
140 //将IEnumerable数据类型转换成DataTable数据类型
141 protected virtual DataTable ConvertToDataTable(IEnumerable data)
142 {
143 DataTable dtReturn = new DataTable();
144
145 foreach (object item in data)
146 {
147 PropertyDescriptorCollection props = TypeDescriptor.GetProperties(item);
148
149 foreach (PropertyDescriptor p in props)
150 {
151 if (!dtReturn.Columns.Contains(p.Name))
152 {
153 dtReturn.Columns.Add(new DataColumn(p.Name, p.PropertyType));
154 }
155 }
156
157 DataRow row = dtReturn.NewRow();
158
159 foreach (PropertyDescriptor p in props)
160 {
161 row[p.Name] = p.GetValue(item);
162 }
163
164 dtReturn.Rows.Add(row);
165 }
166 return dtReturn;
167 }
168
169 //获取数据源,覆盖并重新实现父类方法
170 protected new IEnumerable GetData()
171 {
172 DataSourceView dataSourceView = base.GetData();
173 Type type = dataSourceView.GetType();
174 MethodInfo method = type.GetMethod("ExecuteSelect", BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);
175
176 if (method == null) return null;
177
178 object[] args = new object[] { DataSourceSelectArguments.Empty };
179 object result = method.Invoke(dataSourceView, args);
180
181 return (IEnumerable)result;
182 }
183
184 //为数据筛选行添加样式
185 protected override void PrepareControlHierarchy()
186 {
187 base.PrepareControlHierarchy();
188
189 if (this.Controls.Count != 0)
190 {
191 foreach (TableCell cell in selectorRow.Cells)
192 {
193 if (cell != null && HeaderStyle != null)
194 {
195 cell.MergeStyle(HeaderStyle);
196 }
197 }
198 }
199 }
200
201 //重写排序方法
202 protected override void OnSorting(GridViewSortEventArgs e)
203 {
204 base.OnSorting(e);
205
206 if (DataSource == null) return;
207
208 DataView dataView = ConvertToDataTable(GetData()).DefaultView;
209
210 ViewState["sortexpression"] = e.SortExpression;
211
212 if (ViewState["sortdirection"] == null)
213 {
214 ViewState["sortdirection"] = "asc";
215 }
216 else
217 {
218 if (ViewState["sortdirection"].ToString() == "asc")
219 {
220 ViewState["sortdirection"] = "desc";
221 }
222 else
223 {
224 ViewState["sortdirection"] = "asc";
225 }
226 }
227
228 if (ViewState["sortexpression"] != null)
229 {
230 dataView.Sort = ViewState["sortexpression"].ToString() + " " + ViewState["sortdirection"].ToString();
231 }
232
233 DataSource = dataView;
234 DataBind();
235 }
236 }
237 }



原文地址:https://www.cnblogs.com/chenlinfei/p/2284885.html