本文主要講述如何根據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
|
新聞熱點
疑難解答