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


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM