现在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
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
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
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
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