本文主要讲述如何根据UI配置来动态生成控件, 并添加到窗体上来构建UI窗体,当用户在每个控件上完成输入操作后,程序通过遍历控件并用拼接字符串的方式动态生成Insert SQL语句,进而实现了将UI上的值,保存到数据库。
1 UI配置
首先第一步,需要在数据库中定义UI配置,这里为了简便,用DataTable模拟了数据,如果是复杂的情况,可以再多一些属性的定义,如下所示:
1 //实际从数据库加载
2 DataTable dtUIConfig = new DataTable();
3 dtUIConfig.Columns.Add("name");
4 dtUIConfig.Columns.Add("title");
5 dtUIConfig.Columns.Add("size");
6 dtUIConfig.Columns.Add("location");
7 dtUIConfig.Columns.Add("type");
8 dtUIConfig.Columns.Add("config");
9
10 dtUIConfig.Rows.Add(new object[] { "ID", "ID:", "160,30", "0,0", "textbox", "" });
11 dtUIConfig.Rows.Add(new object[] { "name", "用户名:", "160,30", "0,0", "textbox", "" });
12 dtUIConfig.Rows.Add(new object[] { "password", "密码:", "160,30", "0,0", "passwordtext", "" });
13 dtUIConfig.Rows.Add(new object[] { "sex", "性别:", "160,30", "0,0", "combobox", "Man,Female" });
14 dtUIConfig.Rows.Add(new object[] { "emp", "职员:", "160,30", "0,0", "CustomComboBox", "datagridview" });
15 dtUIConfig.Rows.Add(new object[] { "dept", "部门:", "160,30", "0,0", "CustomComboBox", "treeview" });
16 dtUIConfig.Rows.Add(new object[] { "details", "明细:", "440,200", "0,0", "datagridview", "select * from test" });
17 dtUIConfig.Rows.Add(new object[] { "btnSave", "保存", "160,30", "0,0", "button", "" });
2 获取最长的标签
由于一般的控件,例如文本框等,前面都有一个标签,由于不同的标题长度不一,为了界面整齐,可以动态计算所有标题的长度,并获取最大的长度,作为所有标签的长度。同理获取所有控件的最大配置长度,当然了类似表格等控件需要独立换行,不在此处理范围,如下所示:
1 int leftMargin = 20;
2 int topMargin = 20;
3 int totolwidth = this.Width - 220 - leftMargin;
4
5 Point currentLocation = new Point(leftMargin, topMargin);
6 Point nextLocation = new Point(leftMargin, topMargin);
7 int label_control_width = 2;
8 int y = nextLocation.Y;
9
10 int labelMaxLength = 20;
11 int controlMaxLength = 160;
12
13 int lastY = 0;
14 //UI engine
15 foreach (DataRow dr in dtUIConfig.Rows)
16 {
17
18 //计量字符串长度
19 SizeF maxSize = this.CreateGraphics().MeasureString(dr["title"].ToString(), this.Font);
20 if (labelMaxLength < maxSize.Width)
21 {
22 labelMaxLength = int.Parse(maxSize.Width.ToString("0"));
23 }
24 if (controlMaxLength < int.Parse(dr["size"].ToString().Split(',')[0]))
25 {
26 controlMaxLength = int.Parse(dr["size"].ToString().Split(',')[0]);
27 }
28 }
3 UI Builder
在获得最长的标签后,可以根据UI配置的控件类型,用程序来动态生成控件,并添加到窗体上,如果有自定义的控件,也可以添加,如下所示:
1 //ui builder
2 foreach (DataRow dr in dtUIConfig.Rows)
3 {
4 if (dr["type"].ToString().ToLower() == "button")
5 {
6 Label label = new Label();
7 label.Location = new Point(nextLocation.X, nextLocation.Y);
8 label.Width = labelMaxLength;//max size
9 label.Text ="";
10 //-----------------------------------
11 Button ctrlItem = new Button();
12 ctrlItem.Location = new Point(label.Right + label_control_width, nextLocation.Y);
13 ctrlItem.Width = int.Parse(dr["size"].ToString().Split(',')[0]);
14 ctrlItem.Height = int.Parse(dr["size"].ToString().Split(',')[1]);
15 ctrlItem.Name = dr["name"].ToString();
16 ctrlItem.Text = dr["title"].ToString();
17 // ctrlItem.Font = this.Font;
18 ctrlItem.Click += new EventHandler(ctrlItem_Click);
19 //-------------------------------------------------------------
20 nextLocation.X = ctrlItem.Right + 8;
21 lastY = ctrlItem.Bottom + 16;
22 if (nextLocation.X >= totolwidth)
23 {
24 nextLocation.Y = ctrlItem.Bottom + 16;
25 nextLocation.X = currentLocation.X;
26 }
27 this.Controls.Add(label);
28 this.Controls.Add(ctrlItem);
29
30 }
31
32
33 //-------------------------------------------------
34 if (dr["type"].ToString().ToLower() == "CustomComboBox".ToLower())
35 {
36 Label label = new Label();
37 label.Location = new Point(nextLocation.X, nextLocation.Y);
38 label.Width = labelMaxLength;//max size
39 label.Text = dr["title"].ToString();
40 //-----------------------------------
41
42
43 //datagridview
44 if((dr["config"].ToString().ToLower()=="datagridview"))
45 {
46 CustomComboBox ctrlItem = new CustomComboBox();
47 ctrlItem.Location = new Point(label.Right + label_control_width, nextLocation.Y);
48 ctrlItem.Width = int.Parse(dr["size"].ToString().Split(',')[0]);
49 ctrlItem.Height = int.Parse(dr["size"].ToString().Split(',')[1]);
50 ctrlItem.Name = dr["name"].ToString();
51 DataGridView gridView = new DataGridView();
52 gridView.Columns.Add("ID", "ID");
53 gridView.Columns.Add("Name", "Name");
54 gridView.Columns.Add("Level", "Level");
55 ctrlItem.DropDownControl = gridView;
56 gridView.Rows.Add(new object[] { "001", "jack", "9" });
57 gridView.Rows.Add(new object[] { "002", "wang", "9" });
58 gridView.Font = this.Font;
59 ctrlItem.DropDownControlType = enumDropDownControlType.DataGridView;
60 ctrlItem.DisplayMember = "Name";
61 ctrlItem.ValueMember = "ID";
62 //-------------------------------------------------------------
63 nextLocation.X = ctrlItem.Right + 8;
64 lastY = ctrlItem.Bottom + 16;
65 if (nextLocation.X >= totolwidth)
66 {
67 nextLocation.Y = ctrlItem.Bottom + 16;
68 nextLocation.X = currentLocation.X;
69 }
70 this.Controls.Add(label);
71 this.Controls.Add(ctrlItem);
72 }
73 else if (dr["config"].ToString().ToLower() == "treeview")
74 {
75 CustomComboBox ctrlItem = new CustomComboBox();
76 ctrlItem.Location = new Point(label.Right + label_control_width, nextLocation.Y);
77 ctrlItem.Width = int.Parse(dr["size"].ToString().Split(',')[0]);
78 ctrlItem.Height = int.Parse(dr["size"].ToString().Split(',')[1]);
79 ctrlItem.Name = dr["name"].ToString();
80 //静态变量 2个时候默认就是最后一个
81 treeView1.Font = this.Font;
82 ctrlItem.DropDownControlType = enumDropDownControlType.TreeView;
83 ctrlItem.DropDownControl = this.treeView1;
84 //not empty
85 ctrlItem.DisplayMember = "Name";
86 ctrlItem.ValueMember = "ID";
87 //-------------------------------------------------------------
88 nextLocation.X = ctrlItem.Right + 8;
89 lastY = ctrlItem.Bottom + 16;
90 if (nextLocation.X >= totolwidth)
91 {
92 nextLocation.Y = ctrlItem.Bottom + 16;
93 nextLocation.X = currentLocation.X;
94 }
95 this.Controls.Add(label);
96 this.Controls.Add(ctrlItem);
97
98
99 }
100 else
101 {
102 }
103
104
105 }
106 //---------------------------------------------------------------
107 //强制换行
108 if (dr["type"].ToString().ToLower() == "datagridview")
109 {
110 //Label label = new Label();
111 //label.Location = new Point(nextLocation.X, nextLocation.Y);
112 //label.Width = labelMaxLength;//max size
113 //label.Text = dr["title"].ToString();
114 //-----------------------------------
115 DataGridView ctrlItem = new DataGridView();
116 //强制换行
117 ctrlItem.Location = new Point(currentLocation.X, lastY);
118 ctrlItem.Width = int.Parse(dr["size"].ToString().Split(',')[0]);
119 ctrlItem.Height = int.Parse(dr["size"].ToString().Split(',')[1]);
120 ctrlItem.Name = dr["name"].ToString();
121
122 string connString = "server=.\sql2008r2; database=GC管理; Trusted_Connection=True; ";
123 MkMisII.DAO.SqlHelper.DefaultConnectionString = connString;
124 DataTable dtC = MkMisII.DAO.SqlHelper.GetDataTableBySQL(dr["config"].ToString());
125 if (dtC != null)
126 {
127 ctrlItem.DataSource = dtC;
128 }
129 //-------------------------------------------------------------
130 //nextLocation.X = ctrlItem.Right + 8;
131 //lastY = ctrlItem.Bottom + 16;
132 //if (nextLocation.X >= totolwidth)
133 //{
134 nextLocation.Y = ctrlItem.Bottom + 16;
135 nextLocation.X = currentLocation.X;
136 //}
137
138 this.Controls.Add(ctrlItem);
139
140 }
141 //-------------------------------------------------
142 if (dr["type"].ToString().ToLower() == "textbox")
143 {
144 Label label = new Label();
145 label.Location = new Point(nextLocation.X, nextLocation.Y);
146 label.Width = labelMaxLength;//max size
147 label.Text = dr["title"].ToString();
148 //-----------------------------------
149 TextBox ctrlItem = new TextBox();
150 ctrlItem.Location = new Point(label.Right + label_control_width, nextLocation.Y);
151 ctrlItem.Width = int.Parse(dr["size"].ToString().Split(',')[0]);
152 ctrlItem.Height = int.Parse(dr["size"].ToString().Split(',')[1]);
153 ctrlItem.Name = dr["name"].ToString();
154
155 //-------------------------------------------------------------
156 nextLocation.X = ctrlItem.Right + 8;
157 lastY = ctrlItem.Bottom + 16;
158 if (nextLocation.X >= totolwidth)
159 {
160 nextLocation.Y = ctrlItem.Bottom + 16;
161 nextLocation.X = currentLocation.X;
162 }
163 this.Controls.Add(label);
164 this.Controls.Add(ctrlItem);
165
166 }
167 //----------------------------------------------------------
168 if (dr["type"].ToString().ToLower() == "combobox")
169 {
170 Label label = new Label();
171 label.Location = new Point(nextLocation.X, nextLocation.Y);
172 label.Width = labelMaxLength;
173 label.Text = dr["title"].ToString();
174
175 //-----------------------------------
176 ComboBox ctrlItem = new ComboBox();
177 ctrlItem.Location = new Point(label.Right + label_control_width, nextLocation.Y);
178 ctrlItem.Width = int.Parse(dr["size"].ToString().Split(',')[0]);
179 ctrlItem.Height = int.Parse(dr["size"].ToString().Split(',')[1]);
180 ctrlItem.Name = dr["name"].ToString();
181 string[] items = dr["config"].ToString().Split(',');
182 foreach (string item in items)
183 {
184 ctrlItem.Items.Add(item);
185 }
186 //-------------------------------------------------------------
187 nextLocation.X = ctrlItem.Right + 8;
188 lastY = ctrlItem.Bottom + 16;
189 if (nextLocation.X >= totolwidth)
190 {
191 nextLocation.Y = ctrlItem.Bottom + 16;
192 nextLocation.X = currentLocation.X;
193 }
194
195 this.Controls.Add(label);
196 this.Controls.Add(ctrlItem);
197
198 }
199
200 if (dr["type"].ToString().ToLower() == "passwordtext")
201 {
202 Label label = new Label();
203 label.Location = new Point(nextLocation.X, nextLocation.Y);
204 label.Width = labelMaxLength;
205 label.Text = dr["title"].ToString();
206
207 //-----------------------------------
208 TextBox ctrlItem = new TextBox();
209 ctrlItem.PasswordChar = '*';
210 ctrlItem.Location = new Point(label.Right + label_control_width, nextLocation.Y);
211 ctrlItem.Width = int.Parse(dr["size"].ToString().Split(',')[0]);
212 ctrlItem.Height = int.Parse(dr["size"].ToString().Split(',')[1]);
213 ctrlItem.Name = dr["name"].ToString();
214
215 //-------------------------------------------------------------
216 nextLocation.X = ctrlItem.Right + 8;
217 lastY = ctrlItem.Bottom + 16;
218 if (nextLocation.X >= totolwidth)
219 {
220 nextLocation.Y = ctrlItem.Bottom + 16;
221 nextLocation.X = currentLocation.X;
222 }
223 this.Controls.Add(label);
224 this.Controls.Add(ctrlItem);
225
226 }
227 }
4 生成保存SQL
单击保存按钮,我们通过遍历窗体控件,来动态获取值,然后进行SQL 拼接,有了SQL就可以对数据进行CURD操作了,如下所示:
1 string SQL = "";
2 //save
3 void ctrlItem_Click(object sender, EventArgs e)
4 {
5 try
6 {
7 string preSQL="Insert into Users(";
8 string postSQL = " ) values ( ";
9 foreach (DataRow dr in dtUIConfig.Rows)
10 {
11 if (dr["type"].ToString() != "button" && dr["type"].ToString() != "datagridview")
12 {
13 Control[] ctrl = this.Controls.Find(dr["name"].ToString(), true);
14 if (ctrl != null)
15 {
16 if (ctrl.Length == 1)
17 {
18 if (!dic.Keys.Contains(dr["name"].ToString()))
19 {
20 preSQL += string.Format("'{0}',", dr["name"].ToString());
21 postSQL += string.Format("'{0}',", ctrl[0].Text);
22 //dic.Add(dr["name"].ToString(), ctrl[0].Text);
23 }
24 }
25
26 }
27 }
28
29 }
30 SQL = preSQL.TrimEnd(',') + postSQL.TrimEnd(',') + ")";
31 MessageBox.Show(SQL,"insert SQL");
32 //Save data to database ...
33 }
34 catch (Exception ex)
35 {
36
37 }
38
39 }
5 效果
运行程序,界面如下所示:
大小调整后,会自动进行UI重新布局,如下图所示:
单击保存,生成SQL