转载

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 效果

运行程序,界面如下所示:

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

大小调整后,会自动进行UI重新布局,如下图所示:

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

单击保存,生成SQL

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

正文到此结束
Loading...