你的位置:首页 > ASP.net教程

[ASP.net教程]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 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       }

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           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       }

 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