Fork me on GitHub

C#如何根据配置实现动态窗体

  本文主要讲述如何根据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

posted @ 2015-12-12 06:29  JackWang-CUMT  阅读(12223)  评论(4编辑  收藏  举报