本文主要讲述如何根据UI配置来动态生成控件, 并添加到窗体上来构建UI窗体,当用户在每个控件上完成输入操作后,程序通过遍历控件并用拼接字符串的方式动态生成Insert SQL语句,进而实现了将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", "" });
由于一般的控件,例如文本框等,前面都有一个标签,由于不同的标题长度不一,为了界面整齐,可以动态计算所有标题的长度,并获取最大的长度,作为所有标签的长度。同理获取所有控件的最大配置长度,当然了类似表格等控件需要独立换行,不在此处理范围,如下所示:
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 engine15 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 }
在获得最长的标签后,可以根据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 else101 {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 size113 //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 size147 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 }
单击保存按钮,我们通过遍历窗体控件,来动态获取值,然后进行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 }
运行程序,界面如下所示:
大小调整后,会自动进行UI重新布局,如下图所示:
单击保存,生成SQL
新闻热点
疑难解答