现在FaibClass.Data又新添了两个控件:
DataProvider 数据提供者
DataSource 数据源
现在分别对两个控件作一下介绍
一、DataProvider 根据不同的ProvideType来创建不同的ConnectionString
1
using
System;
2
using
System.ComponentModel;
3
using
System.Drawing.Design;
4
5
namespace
FaibClass.Data.Controls
6
{
7
///
<summary>
8
///
数据对象提供者控件。
9
///
</summary>
10
public
class
DataProvider : Component
11
{
12
private
ProvideType provideType;
13
private
string
connectionString;
14
15
///
<summary>
16
///
数据库操作提供类型。
17
///
</summary>
18
[Description(
"
数据库操作提供类型。
"
)]
19
[DefaultValue(
typeof
(ProvideType),
"
SqlServer
"
)]
20
public
ProvideType ProvideType
21
{
22
get
{
return
provideType; }
23
set
{ provideType
=
value; }
24
}
25
26
///
<summary>
27
///
连接字符串。
28
///
</summary>
29
[Description(
"
连接字符串。
"
)]
30
[DefaultValue((
string
)
null
)]
31
[Editor(
typeof
(ConnectionStringEditor),
typeof
(UITypeEditor))]
32
public
string
ConnectionString
33
{
34
get
{
return
connectionString; }
35
set
{ connectionString
=
value; }
36
}
37
38
///
<summary>
39
///
DataHelper对象实例。
40
///
</summary>
41
[Browsable(
false
)]
42
public
DataHelper Instance
43
{
44
get
45
{
46
object
dhp
=
Activator.CreateInstance(Type.GetType(
"
FaibClass.Data.
"
+
provideType.ToString()),
new
object
[] { connectionString });
47
if
(dhp
!=
null
)
48
return
(DataHelper)dhp;
49
throw
new
Exception(
"
无法创建操作实例
"
);
50
}
51
}
52
}
53
54
///
<summary>
55
///
数据库操作提供类型。
56
///
</summary>
57
public
enum
ProvideType
58
{
59
SqlServer,
60
Oracle,
61
OleDb,
62
Odbc
63
}
64
}
65
关键代码在于ConnectionStringEditor,这是一个编辑器,可以通过传入的ProvideType来显示不同的连接串配置窗口
1
using
System;
2
using
System.Drawing.Design;
3
using
System.ComponentModel;
4
using
System.Windows.Forms;
5
6
namespace
FaibClass.Data.Controls
7
{
8
///
<summary>
9
///
连接字符串编辑器。
10
///
</summary>
11
public
class
ConnectionStringEditor : UITypeEditor
12
{
13
public
ConnectionStringEditor()
14
{
15
}
16
17
public
override
object
EditValue(ITypeDescriptorContext context, IServiceProvider provider,
object
value)
18
{
19
ProvideType currentType
=
((DataProvider)context.Instance).ProvideType;
20
FormConnectionString frm
=
new
FormConnectionString(currentType);
21
if
(value
!=
null
)
22
{
23
frm.ConnectionString
=
(
string
)value;
24
}
25
if
(frm.ShowDialog()
==
DialogResult.OK)
26
{
27
value
=
frm.ConnectionString;
28
}
29
return
value;
30
}
31
32
public
override
UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
33
{
34
return
UITypeEditorEditStyle.Modal;
35
}
36
}
37
}
38
FormConnectionString窗体是为不同类别的数据类型提供配置面板,如下图是创建SqlServer:
最后使用Instance属性来获取DataHelper。
二、DataSource 提供数据源,使用的是继承自BaseModel的类型
1
using
System;
2
using
System.Collections;
3
using
System.ComponentModel;
4
using
System.Drawing.Design;
5
using
System.Text;
6
7
namespace
FaibClass.Data.Controls
8
{
9
///
<summary>
10
///
对象数据源。
11
///
</summary>
12
public
class
DataSource : Component
13
{
14
private
DataProvider provider;
15
private
Type modelType;
16
private
PageArgs pageArgs
=
new
PageArgs();
17
private
QueryBuilder query
=
new
QueryBuilder();
18
19
///
<summary>
20
///
数据提供者。
21
///
</summary>
22
[Description(
"
数据提供者。
"
)]
23
[AttributeProvider(
typeof
(DataProvider))]
24
[DefaultValue((
string
)
null
)]
25
public
DataProvider DataProvider
26
{
27
get
{
return
provider; }
28
set
{ provider
=
value; }
29
}
30
31
///
<summary>
32
///
数据模型。
33
///
</summary>
34
[Description(
"
数据模型。
"
)]
35
[DefaultValue((
string
)
null
)]
36
[Editor(
typeof
(BaseModelEditor),
typeof
(UITypeEditor))]
37
[AttributeProvider(
typeof
(IListSource))]
38
public
Type DataModel
39
{
40
get
{
return
modelType; }
41
set
{ modelType
=
value; }
42
}
43
44
///
<summary>
45
///
分页参数。
46
///
</summary>
47
[Description(
"
分页参数。
"
)]
48
[DefaultValue((
string
)
null
)]
49
public
PageArgs PageArgs
50
{
51
get
{
return
pageArgs; }
52
set
{ pageArgs
=
value; }
53
}
54
55
///
<summary>
56
///
查询构造器。
57
///
</summary>
58
[Description(
"
查询构造器。
"
)]
59
[DefaultValue((
string
)
null
)]
60
public
QueryBuilder QueryBuilder
61
{
62
get
{
return
query; }
63
set
{ query
=
value; }
64
}
65
66
///
<summary>
67
///
生成数据绑定源。
68
///
</summary>
69
///
<returns></returns>
70
public
IList DataBind()
71
{
72
//
未指定数据模型类
73
if
(modelType
==
null
)
74
return
null
;
75
//
未指定提供者实例
76
if
(provider.Instance
==
null
)
77
return
null
;
78
Type type
=
typeof
(DataModelList
<>
);
79
//
获取泛型参数
80
Type gt
=
type.GetGenericTypeDefinition();
81
//
将数据模型类替换到泛型参数
82
Type type1
=
gt.MakeGenericType(modelType);
83
//
创建DataModelList<T>实例
84
IList list
=
(IList)Activator.CreateInstance(type1);
85
//
数据实体
86
BaseModel model
=
(BaseModel)Activator.CreateInstance(modelType);
87
//
填充数据集合
88
try
89
{
90
provider.Instance.FillModelList(list,
"
SELECT * FROM
"
+
model.TableName
+
(query.Length
>
0
?
"
WHERE
"
+
query.ToString() :
""
), PageArgs);
91
return
list;
92
}
93
catch
94
{
95
return
null
;
96
}
97
}
98
}
99
}
100
核心代码是BaseModelEditor
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
BaseModelEditor : UITypeEditor
14
{
15
private
BaseModelUI modelUI;
16
17
public
override
object
EditValue(ITypeDescriptorContext context, IServiceProvider provider,
object
value)
18
{
19
if
(provider
!=
null
)
20
{
21
IWindowsFormsEditorService edSvc
=
(IWindowsFormsEditorService)provider.GetService(
typeof
(IWindowsFormsEditorService));
22
if
(edSvc
==
null
)
23
{
24
return
value;
25
}
26
if
(
this
.modelUI
==
null
)
27
{
28
this
.modelUI
=
new
BaseModelUI(
this
);
29
}
30
this
.modelUI.Start(edSvc, value);
31
edSvc.DropDownControl(
this
.modelUI);
32
value
=
this
.modelUI.Value;
33
this
.modelUI.End();
34
}
35
return
value;
36
}
37
38
///
<summary>
39
///
设置编辑器的弹出样式。
40
///
</summary>
41
///
<param name="context"></param>
42
///
<returns></returns>
43
public
override
UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
44
{
45
return
UITypeEditorEditStyle.DropDown;
46
}
47
48
///
<summary>
49
///
设置编辑器是否可调大小。
50
///
</summary>
51
public
override
bool
IsDropDownResizable
52
{
53
get
54
{
55
return
true
;
56
}
57
}
58
59
///
<summary>
60
///
提供类选择的TreeView。
61
///
</summary>
62
private
class
BaseModelUI : TreeView
63
{
64
private
UITypeEditor editor;
65
private
IWindowsFormsEditorService edSvc;
66
private
object
value;
67
private
ImageList imglist;
68
69
public
BaseModelUI(UITypeEditor editor)
70
{
71
this
.editor
=
editor;
72
base
.Height
=
200
;
73
base
.Width
=
200
;
74
base
.BorderStyle
=
BorderStyle.None;
75
base
.NodeMouseClick
+=
new
TreeNodeMouseClickEventHandler(BaseModelUI_NodeMouseClick);
76
imglist
=
new
ImageList();
77
imglist.ImageSize
=
new
System.Drawing.Size(
16
,
16
);
78
imglist.ColorDepth
=
ColorDepth.Depth32Bit;
79
//
添加图标资源
80
imglist.Images.Add(Properties.Resources._dll.ToBitmap());
81
imglist.Images.Add(Properties.Resources._namespace.ToBitmap());
82
imglist.Images.Add(Properties.Resources._class.ToBitmap());
83
imglist.Images.Add(Properties.Resources._none.ToBitmap());
84
85
base
.ImageList
=
imglist;
86
}
87
88
///
<summary>
89
///
单击选择类
90
///
</summary>
91
///
<param name="sender"></param>
92
///
<param name="e"></param>
93
private
void
BaseModelUI_NodeMouseClick(
object
sender, TreeNodeMouseClickEventArgs e)
94
{
95
if
(e.Node
==
null
)
return
;
96
if
(e.Node.Text
==
"
(无)
"
)
97
{
98
value
=
null
;
99
this
.edSvc.CloseDropDown();
100
return
;
101
}
102
if
(e.Node.Tag
==
null
)
return
;
103
value
=
(Type)e.Node.Tag;
104
this
.edSvc.CloseDropDown();
105
}
106
107
///
<summary>
108
///
109
///
</summary>
110
public
void
End()
111
{
112
this
.edSvc
=
null
;
113
this
.value
=
null
;
114
}
115
116
///
<summary>
117
///
118
///
</summary>
119
///
<param name="edSvc"></param>
120
///
<param name="value"></param>
121
public
void
Start(IWindowsFormsEditorService edSvc,
object
value)
122
{
123
this
.edSvc
=
edSvc;
124
this
.value
=
value;
125
126
this
.Nodes.Clear();
127
this
.Nodes.Add(
"
none
"
,
"
(无)
"
,
3
,
3
);
128
//
枚举当前域中的所有程序集
129
foreach
(Assembly ass
in
AppDomain.CurrentDomain.GetAssemblies())
130
{
131
//
只提exe程序集
132
if
(ass.ManifestModule.Name.ToLower().IndexOf(
"
.exe
"
)
!=
-
1
)
133
{
134
TreeNode node
=
this
.Nodes.Add(ass.GetName().Name, ass.GetName().Name,
0
,
0
);
135
GetTypes(node, ass);
136
//
提程序集中所有引用程序集
137
foreach
(AssemblyName ass1
in
ass.GetReferencedAssemblies())
138
{
139
Assembly ass2
=
Assembly.Load(ass1.FullName);
140
TreeNode node1
=
this
.Nodes.Add(ass1.Name, ass1.Name,
0
,
0
);
141
//
获得程序集中所有类
142
GetTypes(node1, ass2);
143
144
if
(node1.Nodes.Count
==
0
)
145
this
.Nodes.Remove(node1);
146
}
147
148
if
(node.Nodes.Count
==
0
)
149
this
.Nodes.Remove(node);
150
151
break
;
152
}
153
}
154
}
155
156
///
<summary>
157
///
添加类
158
///
</summary>
159
///
<param name="node"></param>
160
///
<param name="ass"></param>
161
private
void
GetTypes(TreeNode node, Assembly ass)
162
{
163
foreach
(Type type
in
ass.GetTypes())
164
{
165
if
(type.IsNotPublic
||
type.IsInterface
||
type.IsEnum)
continue
;
166
//
类必须是继承自BaseModel的
167
if
(type.IsSubclassOf(
typeof
(BaseModel)))
168
{
169
//
命名空间
170
TreeNode nameSpaceNode
=
GetNameSpace(node, type.Namespace);
171
if
(nameSpaceNode
==
null
)
172
{
173
nameSpaceNode
=
node.Nodes.Add(type.Namespace, type.Namespace,
1
,
1
);
174
}
175
TreeNode nodeClass
=
nameSpaceNode.Nodes.Add(type.Name, type.Name,
2
,
2
);
176
nodeClass.Tag
=
type;
177
if
(
this
.value
==
type)
178
{
179
nodeClass.EnsureVisible();
180
base
.SelectedNode
=
nodeClass;
181
}
182
}
183
}
184
}
185
186
private
TreeNode GetNameSpace(TreeNode node,
string
nameSpace)
187
{
188
foreach
(TreeNode child
in
node.Nodes)
189
{
190
if
(child.Text
==
nameSpace)
return
child;
191
}
192
return
null
;
193
}
194
195
///
<summary>
196
///
当前选定的类名称
197
///
</summary>
198
public
object
Value
199
{
200
get
201
{
202
return
this
.value;
203
}
204
}
205
}
206
}
207
}
208