在前说到DataSource的时候,记得有一个属性QueryBuilder,当前并没有加上编辑器,现在效果如下:
这里共用到两个编辑器:QueryParameterEditor和ModelFieldEditor。
1
using
System;
2
using
System.Reflection;
3
using
System.Drawing.Design;
4
using
System.ComponentModel;
5
using
System.Windows.Forms;
6
using
System.Windows.Forms.Design;
7
8
namespace
FaibClass.Data.Controls
9
{
10
///
<summary>
11
///
构造器
12
///
</summary>
13
public
class
QueryParameterEditor : UITypeEditor
14
{
15
16
public
override
object
EditValue(ITypeDescriptorContext context, IServiceProvider provider,
object
value)
17
{
18
//
得到数据模型类型
19
Type model
=
((DataSource)context.Instance).DataModel;
20
FormQueryParemeter frm
=
new
FormQueryParemeter(model);
21
if
(value
!=
null
)
22
{
23
frm.Query
=
(QueryBuilder)value;
24
}
25
if
(frm.ShowDialog()
==
DialogResult.OK)
26
{
27
value
=
frm.Query;
28
}
29
return
value;
30
}
31
32
public
override
UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
33
{
34
return
UITypeEditorEditStyle.Modal;
35
}
36
}
37
}
38
1
using
System;
2
using
System.Reflection;
3
using
System.Drawing.Design;
4
using
System.ComponentModel;
5
using
System.Windows.Forms;
6
using
System.Windows.Forms.Design;
7
8
namespace
FaibClass.Data.Controls
9
{
10
11
///
<summary>
12
///
数据模型字段编辑器
13
///
</summary>
14
public
class
ModelFieldEditor : UITypeEditor
15
{
16
private
ModelFieldUI modelUI;
17
18
public
override
object
EditValue(ITypeDescriptorContext context, IServiceProvider provider,
object
value)
19
{
20
if
(provider
!=
null
)
21
{
22
//
得到数据模型类型
23
Type model
=
((QueryParameter)context.Instance).modelType;
24
IWindowsFormsEditorService edSvc
=
(IWindowsFormsEditorService)provider.GetService(
typeof
(IWindowsFormsEditorService));
25
if
(edSvc
==
null
)
26
{
27
return
value;
28
}
29
if
(
this
.modelUI
==
null
)
30
{
31
this
.modelUI
=
new
ModelFieldUI(
this
, model);
32
}
33
this
.modelUI.Start(edSvc, value);
34
edSvc.DropDownControl(
this
.modelUI);
35
value
=
this
.modelUI.Value;
36
this
.modelUI.End();
37
}
38
return
value;
39
}
40
41
///
<summary>
42
///
设置编辑器的弹出样式。
43
///
</summary>
44
///
<param name="context"></param>
45
///
<returns></returns>
46
public
override
UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
47
{
48
return
UITypeEditorEditStyle.DropDown;
49
}
50
51
///
<summary>
52
///
设置编辑器是否可调大小。
53
///
</summary>
54
public
override
bool
IsDropDownResizable
55
{
56
get
57
{
58
return
true
;
59
}
60
}
61
62
private
class
ModelFieldUI : TreeView
63
{
64
private
UITypeEditor editor;
65
private
IWindowsFormsEditorService edSvc;
66
private
object
value;
67
private
Type modelType;
68
private
ImageList imglist;
69
70
public
ModelFieldUI(UITypeEditor editor, Type type)
71
{
72
this
.editor
=
editor;
73
this
.modelType
=
type;
74
base
.Height
=
200
;
75
base
.Width
=
200
;
76
base
.BorderStyle
=
BorderStyle.None;
77
base
.ShowRootLines
=
false
;
78
base
.ShowPlusMinus
=
false
;
79
base
.NodeMouseClick
+=
new
TreeNodeMouseClickEventHandler(BaseModelUI_NodeMouseClick);
80
imglist
=
new
ImageList();
81
imglist.ImageSize
=
new
System.Drawing.Size(
16
,
16
);
82
imglist.ColorDepth
=
ColorDepth.Depth32Bit;
83
//
添加图标资源
84
imglist.Images.Add(Properties.Resources._const.ToBitmap());
85
86
base
.ImageList
=
imglist;
87
}
88
89
void
BaseModelUI_NodeMouseClick(
object
sender, TreeNodeMouseClickEventArgs e)
90
{
91
if
(
base
.SelectedNode
==
null
)
return
;
92
value
=
e.Node.Text;
93
this
.edSvc.CloseDropDown();
94
}
95
96
///
<summary>
97
///
98
///
</summary>
99
public
void
End()
100
{
101
this
.edSvc
=
null
;
102
this
.value
=
null
;
103
}
104
105
///
<summary>
106
///
107
///
</summary>
108
///
<param name="edSvc"></param>
109
///
<param name="value"></param>
110
public
void
Start(IWindowsFormsEditorService edSvc,
object
value)
111
{
112
this
.edSvc
=
edSvc;
113
this
.value
=
value;
114
115
this
.Nodes.Clear();
116
if
(modelType
!=
null
)
117
{
118
//
取出模型类中静态的字段常量
119
foreach
(FieldInfo finfo
in
modelType.GetFields(BindingFlags.Static
|
BindingFlags.Public
|
BindingFlags.Instance))
120
{
121
if
(finfo.Name
==
"
_TableName
"
||
finfo.Name
==
"
_PrimaryKey
"
)
continue
;
122
string
value1
=
finfo.GetValue(
null
).ToString();
123
TreeNode node
=
new
TreeNode(value1);
124
node.ImageIndex
=
0
;
125
if
(value
!=
null
)
126
{
127
if
(value.ToString()
==
value1)
128
{
129
base
.SelectedNode
=
node;
130
}
131
}
132
base
.Nodes.Add(node);
133
}
134
}
135
}
136
137
///
<summary>
138
///
当前选定的类名称
139
///
</summary>
140
public
object
Value
141
{
142
get
143
{
144
return
this
.value;
145
}
146
}
147
}
148
}
149
}
150
这里还有一个窗体,就是一开始显示的那个图形界面窗体:
1
using
System;
2
using
System.Collections.Generic;
3
using
System.ComponentModel;
4
using
System.Data;
5
using
System.Drawing;
6
using
System.Text;
7
using
System.Windows.Forms;
8
9
namespace
FaibClass.Data.Controls
10
{
11
///
<summary>
12
///
用于编辑查询参数的窗体
13
///
</summary>
14
public
partial
class
FormQueryParemeter : Form
15
{
16
private
Type modelType;
17
18
public
FormQueryParemeter(Type modelType)
19
{
20
InitializeComponent();
21
this
.modelType
=
modelType;
22
}
23
24
public
QueryBuilder Query
25
{
26
get
27
{
28
//
返回当前修改的参数集合
29
QueryParameterCollection collection
=
new
QueryParameterCollection();
30
foreach
(ListViewItem item
in
lvwParameter.Items)
31
{
32
collection.InternalAdd(item.Tag
as
QueryParameterBase);
33
}
34
//
QueryParameterCollection转换到QueryBuilder
35
return
(QueryBuilder)collection;
36
}
37
set
38
{
39
//
将参数集合添加到列表中
40
QueryParameterCollection collection
=
value.QueryParameters.Clone();
41
foreach
(QueryParameterBase p
in
collection)
42
{
43
p.modelType
=
modelType;
44
ListViewItem item
=
MakeItem(p);
45
item.Tag
=
p;
46
lvwParameter.Items.Add(item);
47
}
48
}
49
}
50
51
private
ListViewItem MakeItem(QueryParameterBase p)
52
{
53
string
text
=
""
;
54
int
index
=
0
;
55
if
(p
is
QueryParameter)
56
{
57
text
=
(p
as
QueryParameter).Field;
58
index
=
0
;
59
}
60
//
左括号
61
else
if
(p
is
QueryLeftBracket)
62
{
63
text
=
"
(
"
;
64
index
=
1
;
65
}
66
//
右括号
67
else
if
(p
is
QueryRightBracket)
68
{
69
text
=
"
)
"
;
70
index
=
2
;
71
}
72
ListViewItem item
=
new
ListViewItem(text, index);
73
item.Tag
=
p;
74
return
item;
75
}
76
77
///
<summary>
78
///
添加一个参数
79
///
</summary>
80
///
<param name="sender"></param>
81
///
<param name="e"></param>
82
private
void
btnAdd_Click(
object
sender, EventArgs e)
83
{
84
QueryParameter p
=
new
QueryParameter();
85
p.modelType
=
modelType;
86
ListViewItem item
=
new
ListViewItem(
"
[未定义]
"
,
0
);
87
item.Tag
=
p;
88
lvwParameter.Items.Add(item);
89
item.Selected
=
true
;
90
}
91
92
private
void
左括号ToolStripMenuItem_Click(
object
sender, EventArgs e)
93
{
94
QueryLeftBracket p
=
new
QueryLeftBracket();
95
p.modelType
=
modelType;
96
ListViewItem item
=
new
ListViewItem(
"
(
"
,
1
);
97
item.Tag
=
p;
98
lvwParameter.Items.Add(item);
99
item.Selected
=
true
;
100
}
101
102
private
void
右括号ToolStripMenuItem_Click(
object
sender, EventArgs e)
103
{
104
QueryRightBracket p
=
new
QueryRightBracket();
105
p.modelType
=
modelType;
106
ListViewItem item
=
new
ListViewItem(
"
)
"
,
2
);
107
item.Tag
=
p;
108
lvwParameter.Items.Add(item);
109
item.Selected
=
true
;
110
}
111
112
private
void
pgParemeter_PropertyValueChanged(
object
s, PropertyValueChangedEventArgs e)
113
{
114
if
(lvwParameter.SelectedItems[
0
].Tag
is
QueryParameter)
115
{
116
string
text
=
(lvwParameter.SelectedItems[
0
].Tag
as
QueryParameter).Field;
117
lvwParameter.SelectedItems[
0
].Text
=
string
.IsNullOrEmpty(text)
?
"
[未定义]
"
: text;
118
}
119
}
120
121
private
void
btnOk_Click(
object
sender, EventArgs e)
122
{
123
//
检查左右括号是否匹配
124
int
l
=
0
, r
=
0
;
125
foreach
(ListViewItem item
in
lvwParameter.Items)
126
{
127
if
(item.Tag
is
QueryLeftBracket) l
++
;
128
else
if
(item.Tag
is
QueryRightBracket) r
++
;
129
}
130
if
(r
!=
l)
131
{
132
MessageBox.Show(
"
左右括号没有成对出现,不符合Sql语法规则。
"
,
"
提示
"
, MessageBoxButtons.OK, MessageBoxIcon.Error);
133
return
;
134
}
135
136
DialogResult
=
DialogResult.OK;
137
}
138
139
///
<summary>
140
///
移除
141
///
</summary>
142
///
<param name="sender"></param>
143
///
<param name="e"></param>
144
private
void
btnRemove_Click(
object
sender, EventArgs e)
145
{
146
if
(lvwParameter.SelectedItems.Count
==
0
)
return
;
147
lvwParameter.SelectedItems[
0
].Remove();
148
pgParemeter.SelectedObject
=
null
;
149
lblPg.Text
=
"
{} 的属性:
"
;
150
}
151
152
private
void
lvwParameter_ItemSelectionChanged(
object
sender, ListViewItemSelectionChangedEventArgs e)
153
{
154
if
(e.IsSelected)
155
{
156
pgParemeter.SelectedObject
=
e.Item.Tag;
157
if
(e.Item.Tag
is
QueryParameter)
158
{
159
lblPg.Text
=
(e.Item.Tag
as
QueryParameter).Field
+
"
的属性:
"
;
160
}
161
else
162
{
163
lblPg.Text
=
"
括号 的属性:
"
;
164
}
165
}
166
}
167
168
private
void
btnOther_Click(
object
sender, EventArgs e)
169
{
170
contextMenuStrip1.Show(
this
, btnOther.Left, btnOther.Top
+
btnOther.Height);
171
}
172
173
///
<summary>
174
///
上移
175
///
</summary>
176
///
<param name="sender"></param>
177
///
<param name="e"></param>
178
private
void
btnUp_Click(
object
sender, EventArgs e)
179
{
180
if
(lvwParameter.SelectedItems.Count
==
0
)
181
return
;
182
if
(lvwParameter.SelectedItems[
0
].Index
==
0
)
183
return
;
184
ListViewItem old
=
(ListViewItem)lvwParameter.SelectedItems[
0
].Clone();
185
int
index
=
lvwParameter.SelectedItems[
0
].Index;
186
lvwParameter.Items[index]
=
(ListViewItem)lvwParameter.Items[index
-
1
].Clone();
187
lvwParameter.Items[index
-
1
]
=
old;
188
old.Selected
=
true
;
189
}
190
191
///
<summary>
192
///
下移
193
///
</summary>
194
///
<param name="sender"></param>
195
///
<param name="e"></param>
196
private
void
btnDown_Click(
object
sender, EventArgs e)
197
{
198
if
(lvwParameter.SelectedItems.Count
==
0
)
199
return
;
200
if
(lvwParameter.SelectedItems[
0
].Index
==
lvwParameter.SelectedItems.Count
-
1
)
201
return
;
202
ListViewItem old
=
(ListViewItem)lvwParameter.SelectedItems[
0
].Clone();
203
int
index
=
lvwParameter.SelectedItems[
0
].Index;
204
lvwParameter.Items[index]
=
(ListViewItem)lvwParameter.Items[index
+
1
].Clone();
205
lvwParameter.Items[index
+
1
]
=
old;
206
old.Selected
=
true
;
207
}
208
}
209
}
QueryParameter中的Value是一个object[]类型,所以还提供一个转换器:
1
using
System;
2
using
System.ComponentModel;
3
using
System.Globalization;
4
using
System.Windows.Forms;
5
6
namespace
FaibClass.Data.Controls
7
{
8
///
<summary>
9
///
Object数组转换器
10
///
</summary>
11
public
class
ObjectValueConverter : StringConverter
12
{
13
public
override
bool
CanConvertTo(ITypeDescriptorContext context, Type destinationType)
14
{
15
return
true
;
16
}
17
18
public
override
bool
CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
19
{
20
return
true
;
21
}
22
23
public
override
object
ConvertTo(ITypeDescriptorContext context, CultureInfo culture,
object
value, Type destinationType)
24
{
25
if
(value
==
null
)
26
return
""
;
27
string
ss
=
""
;
28
//
将object[]转换为字符串显示,长度跟QueryBuilder中的Append有关
29
//
效果为 值1,值2
30
foreach
(
object
v
in
(
object
[])value)
31
{
32
ss
+=
v.ToString()
+
"
,
"
;
33
}
34
return
ss.Trim(
'
,
'
);
35
}
36
37
public
override
object
ConvertFrom(ITypeDescriptorContext context, CultureInfo culture,
object
value)
38
{
39
if
(value
==
null
)
40
return
null
;
41
if
(value.ToString().Length
==
0
)
42
return
null
;
43
44
//
将字符串转换为object[]
45
Type model
=
((QueryParameterBase)context.Instance).modelType;
46
Type ptype
=
model.GetProperty(((QueryParameter)context.Instance).Field).PropertyType;
47
//
取模型字段的类型
48
TypeCode tc
=
Type.GetTypeCode(ptype);
49
50
string
[] ss
=
value.ToString().Split(
'
,
'
);
51
object
[] result
=
new
object
[ss.Length];
52
int
i
=
0
;
53
foreach
(
string
v
in
ss)
54
{
55
if
(v.Length
==
0
)
56
{
57
result[i
++
]
=
null
;
58
}
59
else
60
{
61
//
转换
62
result[i
++
]
=
Convert.ChangeType(v.ToString(), tc);
63
}
64
}
65
return
result;
66
}
67
}
68
}
69