当前位置: 代码迷 >> C# >> C#怎么根据配置实现动态窗体
  详细解决方案

C#怎么根据配置实现动态窗体

热度:376   发布时间:2016-04-28 08:28:37.0
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

  相关解决方案