重新封装了一个 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即可
002 |
using System.Collections.Generic; |
003 |
using System.ComponentModel; |
007 |
using System.Web.UI.WebControls; |
008 |
using System.Reflection; |
010 |
namespace xxWare.xxControls |
012 |
[ToolboxData( "<{0}:xxGridView runat=server></{0}:xxGridView>" )] |
013 |
public class xxGridView : System.Web.UI.WebControls.GridView |
017 |
[Browsable( true ) , Category( "Sort Image" ), DefaultValue( "images/arrow_up.gif" ) , Description( "Asc Image" )] |
018 |
public string Asc_Image { get ; set ; } |
019 |
[Browsable( true ), Category( "Sort Image" ), DefaultValue( "images/arrow_down.gif" ), Description( "Desc Image" )] |
020 |
public string Desc_Image { get ; set ; } |
021 |
[Browsable( true ), Category( "Sort Image" ), DefaultValue( "images/arrow_updn.gif" ), Description( "Sortable Image" )] |
022 |
public string Sort_Image { get ; set ; } |
026 |
public string CurrentSortExpression |
028 |
get { return Convert.ToString(ViewState[ "CurrentSortExpression" ]); } |
029 |
set { ViewState[ "CurrentSortExpression" ] = value.Trim(); } |
032 |
public string CurrentSortDirection |
034 |
get { return Convert.ToString(ViewState[ "CurrentSortDirection" ]); } |
037 |
if ( string .IsNullOrEmpty(value)) |
039 |
ViewState[ "CurrentSortDirection" ] = "desc" ; |
043 |
if (value.ToLower() != "asc" && value.ToLower() != "desc" ) |
045 |
ViewState[ "CurrentSortDirection" ] = "desc" ; |
049 |
ViewState[ "CurrentSortDirection" ] = value.ToString().ToLower(); |
056 |
[Category( "MultiSelect" ) , DefaultValue( "True" )] |
057 |
public bool AllowMultiSelect |
059 |
get { return bool .Parse(ViewState[ "AllowMultiSelect" ].ToString()); } |
060 |
set { ViewState[ "AllowMultiSelect" ] = value.ToString(); } |
062 |
[Category( "MultiSelect" ), DefaultValue(0)] |
063 |
public int AllowMultiSelectColumn |
065 |
get { return Int32.Parse(ViewState[ "AllowMultiSelectColumn" ].ToString()); } |
066 |
set { ViewState[ "AllowMultiSelectColumn" ] = value.ToString(); } |
077 |
public List<GridViewRow> MultiSelectedItem |
081 |
if (!AllowMultiSelect) return null ; |
083 |
List<GridViewRow> selectedRows = new List<GridViewRow>(); |
084 |
foreach (GridViewRow row in this .Rows) |
086 |
CheckBox cb = (CheckBox)row.Cells[AllowMultiSelectColumn].Controls[0]; |
089 |
selectedRows.Add(row); |
098 |
private object sourcedata; |
099 |
public object DataSetSource |
103 |
if (sourcedata != null ) |
110 |
sourcedata = value as object ; |
115 |
private int _recordCount = 0; |
117 |
public int RecordCount |
119 |
get { return _recordCount; } |
123 |
[Browsable( true ), Category( "Misc" ), DefaultValue( "True" ), Description( "Auto Pager" )] |
124 |
public bool AutoSort { get ; set ; } |
128 |
private ClientScriptManager csManager; |
130 |
public xxGridView() : base () |
140 |
Asc_Image = @"images/arrow_up.gif" ; |
141 |
Desc_Image = @"images/arrow_down.gif" ; |
142 |
Sort_Image = @"images/arrow_updn.gif" ; |
145 |
Init += new EventHandler(On_Init); |
146 |
Sorting += new GridViewSortEventHandler(On_Sorting); |
147 |
RowCreated += new GridViewRowEventHandler(On_RowCreated); |
150 |
#region Event Handlers |
151 |
public event EventHandler GridBindEvent; |
152 |
public virtual void OnGridBind<T>() |
154 |
if (sourcedata!= null ) |
156 |
if (CurrentSortExpression== string .Empty) |
158 |
this .DataSource = sourcedata; |
164 |
if (sourcedata is DataTable) |
166 |
DataView dv = (sourcedata as DataTable).DefaultView; |
167 |
if (! string .IsNullOrEmpty(CurrentSortExpression) && AutoSort) |
168 |
dv.Sort = CurrentSortExpression + " " + CurrentSortDirection; |
170 |
this .DataSource = dv; |
171 |
_recordCount = dv.Count; |
178 |
if ( this .PageIndex>1) |
186 |
else if (sourcedata is DataSet) |
188 |
DataView dv = (sourcedata as DataSet).Tables[0].DefaultView; |
189 |
if (! string .IsNullOrEmpty(CurrentSortExpression) && AutoSort) |
190 |
dv.Sort = CurrentSortExpression + " " + CurrentSortDirection; |
192 |
this .DataSource = dv; |
193 |
_recordCount = dv.Count; |
200 |
if ( this .PageIndex > 1) |
207 |
else if (sourcedata is List<T>) |
209 |
if (! string .IsNullOrEmpty(CurrentSortExpression) && AutoSort) |
211 |
Reverser<T> reverser = new Reverser<T>( typeof (T), CurrentSortExpression, CurrentSortDirection); |
212 |
(sourcedata as List<T>).Sort(reverser); |
215 |
this .DataSource = sourcedata; |
216 |
_recordCount = (sourcedata as List<T>).Count; |
223 |
if ( this .PageIndex > 1) |
234 |
public void On_Init( object sender, EventArgs e) |
237 |
if (ViewState[ "AllowMultiSelect" ]== null || ViewState[ "AllowMultiSelect" ].ToString().Trim()== "" ) |
238 |
ViewState[ "AllowMultiSelect" ] = "True" ; |
239 |
if (ViewState[ "AllowMultiSelectColumn" ] == null || ViewState[ "AllowMultiSelectColumn" ].ToString().Trim() == "" ) |
240 |
ViewState[ "AllowMultiSelectColumn" ] = "0" ; |
242 |
csManager = this .Page.ClientScript; |
243 |
if (AllowMultiSelect) |
250 |
if (CurrentSortDirection == null || CurrentSortDirection.Trim() == "" ) |
251 |
CurrentSortDirection = "desc" ; |
252 |
if (CurrentSortExpression == null ) CurrentSortDirection = "" ; |
255 |
public void On_Sorting( object sender , GridViewSortEventArgs e) |
257 |
CurrentSortExpression = e.SortExpression; |
258 |
if (CurrentSortDirection == "desc" ) |
259 |
CurrentSortDirection = "asc" ; |
261 |
CurrentSortDirection = "desc" ; |
263 |
GridBindEvent( this , EventArgs.Empty); |
266 |
public void On_RowCreated( object sender , GridViewRowEventArgs e) |
268 |
string currentSortImage = "" ; |
269 |
if (e.Row.RowType==DataControlRowType.Header) |
271 |
foreach (DataControlField field in this .Columns) |
273 |
if (!String.IsNullOrEmpty(field.SortExpression)) |
275 |
if (IsSortedByThisField(field.SortExpression)) |
277 |
currentSortImage = (CurrentSortDirection == "asc" ) ? Asc_Image : Desc_Image; |
281 |
currentSortImage = Sort_Image; |
283 |
AddSortImage(e.Row, this .Columns.IndexOf(field), currentSortImage); |
291 |
#region Override Methods |
292 |
protected override void OnPageIndexChanging(GridViewPageEventArgs e) |
295 |
this .PageIndex = e.NewPageIndex; |
296 |
GridBindEvent( this , EventArgs.Empty); |
300 |
#region private helper function |
302 |
private void AddSortImage(GridViewRow _row, int _colIndex , string _currImage) |
304 |
if (-1 == _colIndex) return ; |
306 |
Image sortImage = new Image(); |
307 |
sortImage.ImageUrl = _currImage; |
308 |
_row.Cells[_colIndex].Controls.AddAt(1, sortImage); |
311 |
private bool IsSortedByThisField(String strSortExpression) |
313 |
return CurrentSortExpression.ToLower() == strSortExpression.Trim().ToLower(); |
317 |
private void AddSelectColumn() |
319 |
TemplateField tc = new TemplateField(); |
320 |
tc.ItemTemplate = new xxGridColumnTemplate(); |
321 |
tc.HeaderTemplate = new xxGridHeaderTemplate(); |
323 |
this .Columns.Insert(AllowMultiSelectColumn, tc); |
325 |
private void RegisterJS() |
337 |
csManager.RegisterClientScriptResource( this .GetType(), "xxWare.xxControls.xxGridViewJS.js" ); |
源码下载(带Demo)
重新封装了一个 GridView,支持如下功能:
1. CheckBox选择记录,指定CheckBox的位置
2. 支持List,DataSet,Datatable 排序
3. 排序时在Header部分出现图标
4. 封装了PageIndexChanged 和DataBind,不用每页都写。
1
using
System;
2
using
System.Collections.Generic;
3
using
System.ComponentModel;
4
using
System.Data;
5
using
System.Web;
6
using
System.Web.UI;
7
using
System.Web.UI.WebControls;
8
using
System.Reflection;
9
10
namespace
xxWare.xxControls
11
{
12
[ToolboxData(
"
<{0}:xxGridView runat=server></{0}:xxGridView>
"
)]
13
public
class
xxGridView : System.Web.UI.WebControls.GridView
14
{
15
#region
Properties
16
//
sort image url : full url = Sort_Image_Url + Asc_Image_Name
17
[Browsable(
true
) , Category(
"
Sort Image
"
), DefaultValue(
"
images/arrow_up.gif
"
) , Description(
"
Asc Image
"
)]
18
public
string
Asc_Image {
get
;
set
; }
19
[Browsable(
true
), Category(
"
Sort Image
"
), DefaultValue(
"
images/arrow_down.gif
"
), Description(
"
Desc Image
"
)]
20
public
string
Desc_Image {
get
;
set
; }
21
[Browsable(
true
), Category(
"
Sort Image
"
), DefaultValue(
"
images/arrow_updn.gif
"
), Description(
"
Sortable Image
"
)]
22
public
string
Sort_Image {
get
;
set
; }
23
24
//
Property : SortExpression
25
[Browsable(
false
)]
26
public
string
CurrentSortExpression
27
{
28
get
{
return
Convert.ToString(ViewState[
"
CurrentSortExpression
"
]); }
29
set
{ ViewState[
"
CurrentSortExpression
"
]
=
value.Trim(); }
30
}
31
[Browsable(
false
)]
32
public
string
CurrentSortDirection
33
{
34
get
{
return
Convert.ToString(ViewState[
"
CurrentSortDirection
"
]); }
35
set
36
{
37
if
(
string
.IsNullOrEmpty(value))
38
{
39
ViewState[
"
CurrentSortDirection
"
]
=
"
desc
"
;
40
}
41
else
42
{
43
if
(value.ToLower()
!=
"
asc
"
&&
value.ToLower()
!=
"
desc
"
)
44
{
45
ViewState[
"
CurrentSortDirection
"
]
=
"
desc
"
;
46
}
47
else
48
{
49
ViewState[
"
CurrentSortDirection
"
]
=
value.ToString().ToLower();
50
}
51
}
52
}
53
}
54
55
//
Property : Multi Show CheckBox
56
[Category(
"
MultiSelect
"
) , DefaultValue(
"
True
"
)]
57
public
bool
AllowMultiSelect
58
{
59
get
{
return
bool
.Parse(ViewState[
"
AllowMultiSelect
"
].ToString()); }
60
set
{ ViewState[
"
AllowMultiSelect
"
]
=
value.ToString(); }
61
}
62
[Category(
"
MultiSelect
"
), DefaultValue(
0
)]
63
public
int
AllowMultiSelectColumn
64
{
65
get
{
return
Int32.Parse(ViewState[
"
AllowMultiSelectColumn
"
].ToString()); }
66
set
{ ViewState[
"
AllowMultiSelectColumn
"
]
=
value.ToString(); }
67
}
68
/*
69
public string RowSelectFilter
70
{
71
get { return (string)ViewState["RowSelectFilter"]; }
72
set { ViewState["RowSelectFilter"] = value.ToString(); }
73
}
74
*
*/
75
//
Property : Get Selected Items
76
[Browsable(
false
)]
77
public
List
<
GridViewRow
>
MultiSelectedItem
78
{
79
get
80
{
81
if
(
!
AllowMultiSelect)
return
null
;
82
83
List
<
GridViewRow
>
selectedRows
=
new
List
<
GridViewRow
>
();
84
foreach
(GridViewRow row
in
this
.Rows)
85
{
86
CheckBox cb
=
(CheckBox)row.Cells[AllowMultiSelectColumn].Controls[
0
];
87
if
(cb.Checked)
88
{
89
selectedRows.Add(row);
90
}
91
}
92
93
return
selectedRows;
94
}
95
}
96
97
//
Define DataSource
98
private
object
sourcedata;
99
public
object
DataSetSource
100
{
101
get
102
{
103
if
(sourcedata
!=
null
)
104
return
sourcedata;
105
else
106
return
null
;
107
}
108
set
109
{
110
sourcedata
=
value
as
object
;
111
}
112
}
113
114
#endregion
115
116
private
ClientScriptManager csManager;
117
118
public
xxGridView() :
base
()
119
{
120
AllowPaging
=
false
;
121
AllowSorting
=
true
;
122
//
GridLines = GridLines.Horizontal;
123
//
BorderWidth = (Unit)0;
124
125
//
Sort Images Default
126
Asc_Image
=
@"
images/arrow_up.gif
"
;
127
Desc_Image
=
@"
images/arrow_down.gif
"
;
128
Sort_Image
=
@"
images/arrow_updn.gif
"
;
129
130
//
set event handlers
131
Init
+=
new
EventHandler(On_Init);
132
Sorting
+=
new
GridViewSortEventHandler(On_Sorting);
133
RowCreated
+=
new
GridViewRowEventHandler(On_RowCreated);
134
}
135
136
#region
Event Handlers
137
public
event
EventHandler GridBindEvent;
138
public
virtual
void
OnGridBind
<
T
>
()
139
{
140
if
(sourcedata
!=
null
)
141
{
142
if
(CurrentSortExpression
==
string
.Empty)
143
{
144
this
.DataSource
=
sourcedata;
145
this
.DataBind();
146
return
;
147
}
148
149
//
Datasource Type
150
if
(sourcedata
is
DataTable)
151
{
152
DataView dv
=
(sourcedata
as
DataTable).DefaultView;
153
if
(
!
string
.IsNullOrEmpty(CurrentSortExpression))
154
dv.Sort
=
CurrentSortExpression
+
"
"
+
CurrentSortDirection;
155
156
this
.DataSource
=
dv;
157
this
.DataBind();
158
}
159
else
if
(sourcedata
is
DataSet)
160
{
161
DataView dv
=
(sourcedata
as
DataSet).Tables[
0
].DefaultView;
162
if
(
!
string
.IsNullOrEmpty(CurrentSortExpression))
163
dv.Sort
=
CurrentSortExpression
+
"
"
+
CurrentSortDirection;
164
165
this
.DataSource
=
dv;
166
this
.DataBind();
167
}
168
else
if
(sourcedata
is
List
<
T
>
)
169
{
170
if
(
!
string
.IsNullOrEmpty(CurrentSortExpression))
171
{
172
Reverser
<
T
>
reverser
=
new
Reverser
<
T
>
(
typeof
(T), CurrentSortExpression, CurrentSortDirection);
173
(sourcedata
as
List
<
T
>
).Sort(reverser);
174
}
175
176
this
.DataSource
=
sourcedata;
177
this
.DataBind();
178
}
179
}
180
181
}
182
183
public
void
On_Init(
object
sender, EventArgs e)
184
{
185
//
processing multi-select
186
if
(ViewState[
"
AllowMultiSelect
"
]
==
null
||
ViewState[
"
AllowMultiSelect
"
].ToString().Trim()
==
""
)
187
ViewState[
"
AllowMultiSelect
"
]
=
"
True
"
;
188
if
(ViewState[
"
AllowMultiSelectColumn
"
]
==
null
||
ViewState[
"
AllowMultiSelectColumn
"
].ToString().Trim()
==
""
)
189
ViewState[
"
AllowMultiSelectColumn
"
]
=
"
0
"
;
190
191
csManager
=
this
.Page.ClientScript;
192
if
(AllowMultiSelect)
193
{
194
AddSelectColumn();
195
RegisterJS();
196
}
197
198
//
processing sorting...
199
if
(CurrentSortDirection
==
null
||
CurrentSortDirection.Trim()
==
""
)
200
CurrentSortDirection
=
"
desc
"
;
201
if
(CurrentSortExpression
==
null
) CurrentSortDirection
=
""
;
202
}
203
204
public
void
On_Sorting(
object
sender , GridViewSortEventArgs e)
205
{
206
CurrentSortExpression
=
e.SortExpression;
207
if
(CurrentSortDirection
==
"
desc
"
)
208
CurrentSortDirection
=
"
asc
"
;
209
else
210
CurrentSortDirection
=
"
desc
"
;
211
212
GridBindEvent(
this
, EventArgs.Empty);
213
}
214
215
public
void
On_RowCreated(
object
sender , GridViewRowEventArgs e)
216
{
217
string
currentSortImage
=
""
;
218
if
(e.Row.RowType
==
DataControlRowType.Header)
219
{
220
foreach
(DataControlField field
in
this
.Columns)
221
{
222
if
(
!
String.IsNullOrEmpty(field.SortExpression))
223
{
224
if
(IsSortedByThisField(field.SortExpression))
225
{
226
currentSortImage
=
(CurrentSortDirection
==
"
asc
"
)
?
Asc_Image : Desc_Image;
227
}
228
else
229
{
230
currentSortImage
=
Sort_Image;
231
}
232
AddSortImage(e.Row,
this
.Columns.IndexOf(field), currentSortImage);
233
}
234
}
235
}
236
}
237
238
#endregion
239
240
#region
Override Methods
241
protected
override
void
OnPageIndexChanging(GridViewPageEventArgs e)
242
{
243
//
base.OnPageIndexChanging(e);
244
this
.PageIndex
=
e.NewPageIndex;
245
GridBindEvent(
this
, EventArgs.Empty);
246
}
247
#endregion
248
249
#region
private helper function
250
//
For Sort
251
private
void
AddSortImage(GridViewRow _row,
int
_colIndex ,
string
_currImage)
252
{
253
if
(
-
1
==
_colIndex)
return
;
254
255
Image sortImage
=
new
Image();
256
sortImage.ImageUrl
=
_currImage;
257
_row.Cells[_colIndex].Controls.AddAt(
1
, sortImage);
258
}
259
260
private
bool
IsSortedByThisField(String strSortExpression)
261
{
262
return
CurrentSortExpression.ToLower()
==
strSortExpression.Trim().ToLower();
263
}
264
265
//
for Multi Select
266
private
void
AddSelectColumn()
267
{
268
TemplateField tc
=
new
TemplateField();
269
tc.ItemTemplate
=
new
FarGridColumnTemplate();
270
tc.HeaderTemplate
=
new
FarGridHeaderTemplate();
271
272
this
.Columns.Insert(AllowMultiSelectColumn, tc);
273
}
274
private
void
RegisterJS()
275
{
276
/*
277
System.Resources.ResourceManager rm = new System.Resources.ResourceManager("xxGridView", Assembly.GetExecutingAssembly());
278
string _script = rm.GetString("js_selectall");
279
280
if (!csManager.IsClientScriptBlockRegistered(this.GetType() , "js_selectall"))
281
{
282
csManager.RegisterClientScriptBlock(this.GetType(), "js_selectall", _script);
283
}
284
*/
285
286
csManager.RegisterClientScriptResource(
this
.GetType(),
"
xxWare.xxControls.xxGridViewJS.js
"
);
287
}
288
289
#endregion
290
291
}
292
}
还有一些如: MultiSelectFilter 等有时间再完善