运行时 Windows 窗体设计






4.74/5 (62投票s)
Panel 被用作窗体,用户可以在其中添加、移动控件,用户可以使用属性窗口添加文本、项目、颜色等。将数据绑定到 DatagridView、ListView、ComboBox,数据源为 DataTable、XML 文件和 SQL Server 数据库。
引言
运行时 Windows 窗体设计允许用户在运行时设计窗体、保存窗体、打开和重用现有窗体。用户可以从工具栏在运行时添加控件,设计他们的窗体,编写控件的代码以执行某些操作。现在,例如,用户可以在运行时添加一个 DataGridView
和一个 Button 控件。在代码部分文本框中,用户可以添加他们的代码以从数据库绑定数据到选定的 Data Grid。所有这些都在运行时完成。
此运行时 Windows 窗体设计将对以下人群有用:
- 项目经理/系统分析员,他们可以为新项目进行设计,然后移交给开发程序员和软件工程师。
- 向客户演示项目。在某些情况下,客户需要当场设计窗体并提供窗体外观的示例输出。在这种情况下,此应用程序将非常有用,可以在短时间内设计他们的窗体并进行演示。
- 教学和培训新程序员或开发人员。培训师或老师可以向新程序员解释基本的 Windows 窗体控件、每个控件的属性以及如何编写简单的代码。
运行时 Windows 窗体设计软件应用程序的开发目的是使用 Panel 控件设计您自己的窗体,添加 Label
、Button
、TextBox
、ListBox
、DataGridView
、ListView
、CheckBox
等。用户可以添加/更改窗体的背景颜色/图像(此处,我们使用 Panel
)。用户可以使用属性窗口向 ComboBox
、TreeView
、listView
、Textbox
添加项目。用户可以在底部的 textbox
中输入自己的 C# 代码以在运行时运行他们的代码,例如,添加一个 Button,然后在 Textbox 中添加您的代码,然后单击 Button 以查看运行时 Button Click 事件。在此程序中,我在单击 Button
时添加了一个简单的 MessageBox
显示。我计划将此功能扩展到从 XML、数据库 Datagridview
绑定数据。使用此应用程序,用户可以从 DataTable
、XML 文件和 SQL 数据源绑定数据。这个简单的 C# 应用程序允许用户添加
- 创建新窗体
- 将窗体保存为 XML 文件
- 从 XML 文件打开窗体
- 剪切、复制和粘贴所有控件
- 删除所有控件
- 删除选定控件
- 为窗体添加/更改背景颜色(此处,Panel 用作窗体)
- 为窗体添加/更改背景图像
- 添加
Label
控件并使用属性窗口设计您的Label
- 添加
Button
控件并使用属性窗口设计您的Button
- 添加
CheckBox
控件并使用属性窗口设计您的CheckBox
.. - 添加
Button
控件并使用属性窗口设计您的Button
- 添加
ComboBox
控件并使用属性窗口设计您的ComboBox
- 添加
DataGridView
控件并使用属性窗口设计您的DataGridView
- 添加
DataTimePicker
控件并使用属性窗口设计您的DataTimePicker
- 添加
ListBox
控件并使用属性窗口设计您的ListBox
- 添加
ListView
控件并使用属性窗口设计您的ListView
- 添加
NumericUpDown
控件并使用属性窗口设计您的NumericUpDown
- 添加
PictureBox
控件并使用属性窗口设计您的PictureBox
- 添加
RadioButton
控件并使用属性窗口设计您的RadioButton
- 添加
TextBox
控件并使用属性窗口设计您的TextBox
- 添加
TreeView
控件并使用属性窗口设计您的TreeView
- 将 DataTable 返回的数据绑定到 DataGridView、ListView、ComboBox 和 ListBox
- 将 XML 文件数据作为 DataTable 返回的数据绑定到 DataGridView、ListView、ComboBox 和 ListBox
- 将 SQL Server 数据库数据作为 DataTable 返回的数据绑定到 DataGridView、ListView、ComboBox 和 ListBox
应用程序布局
在此应用程序中,我们可以看到左侧有工具栏,用于将控件添加到窗体(这里是我们的 Panel
)。中心有一个窗体(Panel
),用户可以在其中添加和设计他们的控件。右侧有属性窗口,用于将所有设计添加到选定的控件。底部有一个用于代码部分的TextBox,用户可以在其中编写运行时生成的 Button Click 事件的代码。
工具栏
在这里,我们可以看到可以在运行时添加到窗体的所有控件列表。版本 1.2 中已添加新功能。新功能包括创建新窗体、保存窗体、打开窗体、剪切、复制和粘贴控件。
窗体(作为 Panel)
在这里,我们可以看到中心的窗体(Panel
),用户可以在其中添加他们的控件,并且我们可以在 Button Click 后看到 Message Box。
Property Window (属性窗口)
在右侧,我们有属性窗口,它将有助于用户设计他们的控件。
代码部分
在底部,我们可以看到代码部分,用户可以在其中编写自己的代码。它有两个部分:第一个 Panel
包含“选择要绑定的控件” ComboBox
。每当用户将控件添加到窗体(Panel
)时,控件名称都会添加到此 Combobox
中。这里,我们可以看到现在“grid_20
”是添加到 Form
的 DatagridView
的名称。
在“代码类型”中,用户可以选择 Button Click 事件类型为“MessageBox”、“Dat Tablereturn”、“XML Data table Return”、“SQL Data Base to Data Table return”,接下来,我们有一个 Textbox,用户可以在其中输入他们的代码。下面,您可以看到创建 Datatable
并向 Datatable
添加带数据的行,最后返回 DataTable 的代码。
这里,我们可以看到“选择要绑定的控件” ComboBox
。这里,我们可以看到已添加到我们窗体的控件列表,如 Grid
、Label
、Button
、ListView
等。我使用了带控件类型前缀 3 个字符和随机数的控件名称。
消息框
这里,我们可以看到一个示例,演示如何从 Button Click 在运行时显示 Message Box。
从 DataTable 和 XML 文件绑定控件
在这里,我们可以看到已添加 Label
、ListBox
、ComboBox
、DatagridView
、ListView
和 Button
等控件。我们在选择需要绑定的控件时要小心,并且我们可以选择我们的函数类型为“Dat Table return
”。
注意:仅在 Button Click 事件中,我们才能绑定控件。所以选择你的控件来绑定,例如,combobox
或 ListBox
或你想要的任何控件,然后在 Textbox
中,输入你的代码来返回可以绑定到你所选控件的 datatable
。
这里是用于将数据绑定到选定控件的示例代码列表。只需复制此代码并将其粘贴到代码部分的 TextBox 中。
//--for return Datatable to Combobox/ListBox
DataTable dt = new DataTable();
dt.Columns.Add("itemCode");
dt.Columns.Add("ItemName");
DataRow row = dt.NewRow();
row["itemCode"] = "0001";
row["ItemName"] = "SHANU";
dt.Rows.Add(row);
row = dt.NewRow();
row["itemCode"] = "0002";
row["ItemName"] = "Afraz";
dt.Rows.Add(row);
row = dt.NewRow();
row["itemCode"] = "0003";
row["ItemName"] = "Afreen";
dt.Rows.Add(row);
return dt;
//----------------- For return Datatable to from XML FIle
//You can find the "ShanuDataSource.xml" XML file at my bin folder of Zip file.
//If you want to load your XML File Place it in the same Bin Folder.
DataSet dataSet = new DataSet();
dataSet.ReadXml("ShanuDataSource.xml");
return dataSet.Tables[0];
// ----------------- From SQL SERVER Data Base to Data Table.
string constring = @"Data Source=YourServerName;
Initial Catalog=YourDBName;User id = sa;password=YourPWD";
SqlConnection con = new SqlConnection(constring);
SqlCommand cmd = new SqlCommand("select * from ItemMasters", con);
cmd.CommandType = CommandType.Text;
SqlDataAdapter sda = new SqlDataAdapter(cmd);
DataTable dt = new DataTable();
sda.Fill(dt);
return dt;
从 SQL Server 数据库绑定控件
在这里,我们可以看到一个示例,演示如何在运行时通过 Button Click 将 SQL Server 数据库表数据作为 DataTable 返回到 DataGridView
。
Using the Code
此应用程序中的主要代码部分是在运行时添加控件并创建事件,如 Mouse Enter、Mouse Leave、Resize Control、Mouse Move、Mouse Down,以及在运行时创建类并在运行时编译代码。所有代码部分都已很好地注释,用户可以轻松理解代码。
窗体背景
在这里,我使用了 Panel
控件作为 Form
。我使用了 ColorDialog
和 OpenFileDialog
来更改 Form
(Panel
)的 BackColor
和 Background
图像。
private void frmbackColor_Click(object sender, EventArgs e)
{
ColorDialog colorDlg = new ColorDialog();
if (colorDlg.ShowDialog() == DialogResult.OK)
{
if (pnControls.BackgroundImage != null)
{
pnControls.BackgroundImage.Dispose();
pnControls.BackgroundImage = null;
}
pnControls.BackColor = colorDlg.Color;
}
}
//////////////////////////////////
/// To Add/Change the panel Background Image.
private void frmBackGround_Click(object sender, EventArgs e)
{
OpenFileDialog dialog = new OpenFileDialog();
dialog.Filter = "JPEG Files (*.jpeg)|*.jpeg|PNG Files
(*.png)|*.png|JPG Files (*.jpg)|*.jpg|GIF Files (*.gif)|*.gif";
dialog.Title = "Select Your Form background Image File";
if (dialog.ShowDialog() == DialogResult.OK)
{
pnControls.BackgroundImage = Image.FromFile(dialog.FileName);
}
}
/////////////////////////////
删除控件
为了删除所有控件和选定控件,我使用了 public
变量 SelectedControl
,它将存储当前选定的控件。
/// To delete a selected control from mainPanel(OurForm)
private void DeleteSTool_Click(object sender, EventArgs e)
{
if (SelectedControl != null)
{
pnControls.Controls.Remove(SelectedControl);
propertyGrid1.SelectedObject = null;
pnControls.Invalidate();
}
}
//////////////////////////////////
/// To delete all controls placed in mainPanel(OurForm)
private void DeleteATool_Click(object sender, EventArgs e)
{
pnControls.Controls.Clear();
propertyGrid1.SelectedObject = null;
pnControls.Invalidate();
}
添加控件
从工具栏,用户可以将控件添加到 Form
(Panel
)。现在,例如,要将 DataTimePicker
添加到窗体,我们可以看到下面的代码。我在运行时创建 DataTimePicker
并将控件添加到窗体(Panel
)。我添加了运行时控件事件,如 MoverEnter
、MouseLeave
、MouseDown
。使用这些事件,可以在窗体(Panel
)内部移动、调整运行时控件的大小以进行设计。与此类似,我添加了所有其他控件,如 Textbox
、Button
、Label
等。
///To add DateTimePicker control to Panel(Form)
private void DateTimeTool_Click(object sender, EventArgs e)
{
Random rnd = new Random();
int randNumber = rnd.Next(1, 1000);
String DatetimeName = "dte_" + randNumber;
DateTimePicker ctrl = new DateTimePicker();
ctrl.Location = new Point(70, 30);
ctrl.Name = DatetimeName;
ctrl.Font = new System.Drawing.Font("NativePrinterFontA", 10F,
System.Drawing.FontStyle.Regular,
System.Drawing.GraphicsUnit.Point, ((byte)(0)));
ctrl.Text = DateTime.Now.ToString();
ctrl.MouseEnter += new EventHandler(control_MouseEnter);
ctrl.MouseLeave += new EventHandler(control_MouseLeave);
ctrl.MouseDown += new MouseEventHandler(control_MouseDown);
ctrl.MouseMove += new MouseEventHandler(control_MouseMove);
ctrl.MouseUp += new MouseEventHandler(control_MouseUp);
// ctrl.Click += new EventHandler(control_Click);
pnControls.Controls.Add(ctrl);
}
运行时控件移动和调整大小
将控件添加到窗体(Panel
)后,需要移动、调整大小并为选定控件分配属性。所有这些功能都将在此处添加。
/// RUN time Control Mouse Down Event used for Control Move
private void control_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
pnControls.Invalidate(); //unselect other control
SelectedControl = (Control)sender;
Control control = (Control)sender;
mouseX = -e.X;
mouseY = -e.Y;
control.Invalidate();
DrawControlBorder(sender);
propertyGrid1.SelectedObject = SelectedControl;
}
}
//////////////////////////////////
/// RUN time Control Mouse Move Event used for Control Move
///
private void control_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
Control control = (Control)sender;
Point nextPosition = new Point();
nextPosition = pnControls.PointToClient(MousePosition);
nextPosition.Offset(mouseX, mouseY);
control.Location = nextPosition;
Invalidate();
}
}
运行时类创建
我们需要为运行时 Button Click 事件执行代码。下面的函数将在运行时创建一个类,我们从运行时 Button Control Click 事件将我们的代码部分 TextBox
文本传递给此函数。
/// When Runtime Control clicks this event trigger here,
/// we can write our code for runtime control click.
/// Here in this click event, I have called RunTimeCodeGenerate method.
/// This method will create class at runtime and run your code.
///
private void control_Click(object sender, EventArgs e)
{
if (rdoMessage.Checked == true)
{
RunTimeCodeGenerate(txtCode.Text.Trim());
}
else if (rdoDataTable.Checked == true)
{
RunTimeCodeGenerate_ReturnTypeDataTable(txtCode.Text.Trim());
}
else if (rdoXML.Checked == true)
{
RunTimeCodeGenerate_ReturnTypeDataTable(txtCode.Text.Trim());
}
else if (rdoDatabase.Checked == true)
{
RunTimeCodeGenerate_ReturnTypeDataTable(txtCode.Text.Trim());
}
}
///This function will create a Runtime Class and add all our runtime code.
public void RunTimeCodeGenerate(String yourCodeHere)
{
try
{
string code = @"
using System;
using System.Xml;
using System.Data;
namespace SHANUFormDesing
{
public class Program
{
public static void Main()
{
YourCodeHere
}
}
}
";
string finalCode = code.Replace("YourCodeHere", yourCodeHere);
CSharpCodeProvider provider = new CSharpCodeProvider();
CompilerParameters parameters = new CompilerParameters();
// Reference to System.Drawing library
parameters.ReferencedAssemblies.Add("System.Windows.Forms.dll");
parameters.ReferencedAssemblies.Add("System.Drawing.dll");
parameters.ReferencedAssemblies.Add("System.Data.dll");
parameters.ReferencedAssemblies.Add("System.Xml.dll");
parameters.ReferencedAssemblies.Add("System.dll");
// parameters.ReferencedAssemblies.Add("System.Data.SqlClient.dll");
parameters.GenerateInMemory = true;
// True - exe file generation, false - dll file generation
parameters.GenerateExecutable = true;
CompilerResults results =
provider.CompileAssemblyFromSource(parameters, finalCode);
if (results.Errors.HasErrors)
{
StringBuilder sb = new StringBuilder();
foreach (CompilerError error in results.Errors)
{
sb.AppendLine(String.Format("Error ({0}): {1}",
error.ErrorNumber, error.ErrorText));
}
throw new InvalidOperationException(sb.ToString());
}
Assembly assembly = results.CompiledAssembly;
Type program = assembly.GetType("SHANUFormDesing.Program");
MethodInfo main = program.GetMethod("Main");
main.Invoke(null, null);
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
///This function will create at Runtime and this class has a method with return
// type as DataTable. Users can write their own code in textbox to return the data
// Table and bind to the selected Controls.
public void RunTimeCodeGenerate_ReturnTypeDataTable(String yourCodeHere)
{
try
{
string code = @"
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using Microsoft.CSharp;
using System.CodeDom.Compiler;
using System.Reflection;
using System.Data.SqlClient;
using System.IO;
namespace SHANUFormDesing
{
public class Program
{
public static void Main()
{
}
public static DataTable returnDTS()
{
YourCodeHere;
}
}
}
";
string finalCode = code.Replace("YourCodeHere", yourCodeHere);
CSharpCodeProvider provider = new CSharpCodeProvider();
CompilerParameters parameters = new CompilerParameters();
// Reference to System.Drawing library
parameters.ReferencedAssemblies.Add("System.Windows.Forms.dll");
parameters.ReferencedAssemblies.Add("System.Drawing.dll");
parameters.ReferencedAssemblies.Add("System.Data.dll");
parameters.ReferencedAssemblies.Add("System.Xml.dll");
parameters.ReferencedAssemblies.Add("System.dll");
// parameters.ReferencedAssemblies.Add("System.Data.SqlClient.dll");
parameters.GenerateInMemory = true;
// True - exe file generation, false - dll file generation
parameters.GenerateExecutable = true;
CompilerResults results =
provider.CompileAssemblyFromSource(parameters, finalCode);
if (results.Errors.HasErrors)
{
StringBuilder sb = new StringBuilder();
foreach (CompilerError error in results.Errors)
{
sb.AppendLine(String.Format("Error ({0}): {1}",
error.ErrorNumber, error.ErrorText));
}
throw new InvalidOperationException(sb.ToString());
}
Assembly assembly = results.CompiledAssembly;
Type program = assembly.GetType("SHANUFormDesing.Program");
MethodInfo main = program.GetMethod("returnDTS");
object ds = main.Invoke(null, null);
DataTable dt = (DataTable)ds;
foreach (Control pnlCntl in pnControls.Controls)
{
// DataGridView Data Bind from Data Table and from XML Data Source.
if (pnlCntl is DataGridView)
{
if (pnlCntl.Name == ComboControlNames.SelectedItem.ToString())
{
DataGridView grid = (DataGridView)pnlCntl;
grid.DataSource = dt;
}
}
else if (pnlCntl is ListView) // ListView Data Bind from Data Table
// and from XML Data Source.
{
if (pnlCntl.Name == ComboControlNames.SelectedItem.ToString())
{
ListView lstView = (ListView)pnlCntl;
lstView.View = View.Details;
foreach (DataColumn column in dt.Columns)
{
lstView.Columns.Add(column.ColumnName);
}
foreach (DataRow row in dt.Rows)
{
ListViewItem item = new ListViewItem(row[0].ToString());
for (int i = 1; i < dt.Columns.Count; i++)
{
item.SubItems.Add(row[i].ToString());
}
lstView.Items.Add(item);
}
}
}
else if (pnlCntl is ComboBox) // ComboBox Data Bind from Data Table
// and from XML Data Source.
{
if (pnlCntl.Name == ComboControlNames.SelectedItem.ToString())
{
ComboBox cmbo = (ComboBox)pnlCntl;
cmbo.DataSource =dt;
cmbo.DisplayMember = "ItemName";
cmbo.ValueMember = "itemCode";
}
}
else if (pnlCntl is ListBox) // ListBox Data Bind from Data Table
// and from XML Data Source.
{
if (pnlCntl.Name == ComboControlNames.SelectedItem.ToString())
{
ListBox lstBox = (ListBox)pnlCntl;
lstBox.DataSource = dt;
lstBox.DisplayMember = "ItemName";
lstBox.ValueMember = "itemCode";
}
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
关注点
我有一个未来的计划,将此应用程序扩展并添加功能,如新建、保存和打开窗体、通过 XML 和数据库的代码部分绑定控件。
已添加新功能。现在用户可以使用相同的代码,在运行时将 DataTable
、XML 文件和 SQL Server DataBase
的数据绑定到 DataGridView
、ListView
、ComboBox
、ListBox
。我们将在本文中详细介绍如何从 XML 和 SQL 数据库绑定数据。下载最新的源代码版本“SHANUFormDesing_V1.3zip”。
注意:在我的 zip 文件 bin 文件夹中,您可以看到一个“FormDesign.txt”。在此文本文件中,我添加了一个可以用于代码部分加载数据的示例代码。我附加了“ShanuDataSource.xml”XML 文件用于从 XML 加载数据。
我已添加了之前提到的所有功能,如新建、保存、打开、剪切、复制和粘贴控件,以及从 XML 和 SQL Server 数据库绑定数据。您可以下载 V1.3 的最新 zip 文件版本,该版本现可在本文顶部下载。我还有更多计划,为 Shanu 窗体设计应用程序添加更多功能。欢迎对此文章的读者提出评论。
此应用程序的基本想法来自我之前的文章 Drawing in Windows Forms。
参考
以下 CodeProject 文章帮助我创建了一个类并在运行时进行编译
历史
- 2014 年 9 月 26 日:初次发布
- 2014 年 9 月 29 日:已添加新功能,如在运行时从用户输入的代码生成的运行时 Button 中,将
DataTable
、XML 文件和 SQL Server 数据库的数据绑定到DataGridView
、ListView
、ComboBox
和ListBox
。 - 2014 年 9 月 29 日:已添加新功能,可创建新窗体、保存窗体并以 XML 格式打开窗体。剪切、复制和粘贴控件
- 2014 年 9 月 30 日:更新了源代码