• 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

  • 相关阅读:
    获取指定<文字行数>的<高度>是多少 TextKit
    JS 与 OC 交互
    PHP-note
    MySQL函数
    freeSWITCH之多平台测试通信
    freeSWITCH之安装
    PHP面向对象
    MySQL Optimization 优化原理
    理解常量指针与指针常量?
    InterView之PHP(2)
  • 原文地址:https://www.cnblogs.com/isaboy/p/csharp_dynamic_generate_form.html
Copyright © 2020-2023  润新知