通常在写程序的时候当要用到某些组件采用的方法一般都是动态创建用完以后就释放掉Visual C#在程序运行的时候也可以动态创建组件下面就结合一个程序例子来具体介绍如何用Visual C#动态生成组件首先让我们了解一下在动态创建组件的过程中要用到的一些概论和理论
一. Boxing (装箱)和Unboxing (出箱)
在用Visual C#动态创建组件的时候要涉及到二种数据类型变量的转换这二种类型变量就是实值类型(Value Type)变量和参考类型(Reference Type)变量而这种转换过程在Visual C#中被称为Boxing (装箱)和Unboxing (出箱)其中把实值类型变量转换成参考类型变量就是Boxing (装箱)把参考类型变量转换成实值类型变量就是Unboxing (出箱)那么什么是实值类型说的简单些就是我们平常使用的整型布尔型枚举型等这些类型的变量就是实值类型变量了所谓参考类型在Visual C#中指的就是ObjectClassInterfaceDelegateStringArray等他和实值类型最主要的不同之处就是参考类型变量存放的是指向实体对象的指针而实值类型变量却是实实在在地实体对象在本文介绍的程序中主要涉及的是出箱具体的处理方法在下面有着具体介绍
二. 程序设计中的关键步骤以及解决方法
文中软件主要功能是用通过窗体上的二个按钮来创建二个不同类型的WinForm组件Button组件和TextBox组件并在创建的同时为每一个组件的属性赋值给每一个创建的组件也创建了事件
()如何在窗体上创建Button组件
其实用Visual C#创建一个组件是十分方便的只用下列二行语句就可以完成了
//创建一个新的Button组件
Button myButton = new Button ( ) ;
//在窗体中显示此按钮
thisControlsAdd ( myButton ) ;
但此时创建的这个Button组件没有任何属性并且也没有任何事件在本文中介绍的程序中创建的Button组件不仅有属性也有事件下列语句就是本文程序创建Button组件源代码
//按钮数量计算器在每次按钮按动后加
counter += ;
//对要产生的按钮的纵坐标的相对位置是前一个产生按钮的相对位置的纵坐标加
locY += thisbtnAddHeight + ;
//创建一个新的Button组件
Button myButton = new Button ( ) ;
//设定他的名称和Text属性以及产生的相对位置
myButtonName = Button + counter ;
myButtonText = 按钮 + counter ;
myButtonLocation = new Point ( btnAddLocationX locY ) ;
//为产生的新的Button组件设定事件本文中为产生的按钮设定了三个事件
myButtonMouseEnter += new SystemEventHandler ( thisbtn_MouseEnter ) ;
myButtonMouseLeave += new SystemEventHandler ( thisbtn_MouseLeave ) ;
myButtonClick += new SystemEventHandler ( thisbtn_Click ) ;
//在窗体中显示此按钮
thisControlsAdd ( myButton ) ;
程序不仅为每一个组件的属性都赋值而且为每一个组件都创建了三个事件细心的读者可能已经注意到程序为每一个组件创建的事件的名称都是一样的这样就有一个问题如何在这一样的事件中识别到底是哪个Button组件触发了事件
()确定是哪个组件触发了事件
由于程序中为每一个创建的Button组件的事件都是一样的要想正确处理这些组件的事件就需要在事件触发的程序中判断到底是哪个组件触发了这个事件这就需要用到上面所提出的装箱和出箱我们知道Sender对象是一个参考类型变量他存放的是指向触发当前事件实体对象的指针要把他给转换成实值对象类型通过下列语句就可以确定是哪个组件触发了当前事件
private void btn_MouseEnter ( object sender SystemEventArgs e )
{
//出箱
Button currentButton = ( Button ) sender ;
//设定按钮的背景色
currentButtonBackColor = ColorRed ;
}
其他事件可以仿照此事件的处理过程来处理
() 如何在窗体上创建TextBox组件
创建TextBox组件的过程和创建Button组件过程相类似只是在创建的组件类型上面有一点区别具体实现语句如下
//文本框数量计算器在每次按钮按动后加
counter += ;
//对要产生的文本框的纵坐标的相对位置是前一个产生按钮的相对位置的纵坐标加
locY += thistxtAddHeight + ;
//创建一个新的TextBox组件
TextBox myBox = new TextBox ( ) ;
//设定他的名称和Text属性以及产生的位置
myBoxName = TextBox + counter ;
myBoxText = 文本框 + counter ;
myBoxLocation = new Point ( txtAddLocationX locY ) ;
//为产生的新的TextBox组件设定事件本文中为产生的文本框设定了一个事件
myBoxClick += new SystemEventHandler ( thisbtn_Click ) ;
//在窗体中显示此文本框
thisControlsAdd ( myBox ) ;
此时细心的读者又会发现为每一个TextBox组件创建Click事件和为Button组件创建的Click事件也是一样的这样在Click事件中不仅要判断是哪个组件触发了事件还要判断是那种类型的组件触发了事件下面语句是实现这些判断地具体方法
private void btn_Click ( object sender SystemEventArgs e )
{
if ( senderGetType ( ) == typeof ( Button ) )
{
Button control = ( Button ) sender ;
MessageBoxShow ( controlText + 被按动了!);
}
else
{
TextBox control = ( TextBox ) sender ;
MessageBoxShow ( controlText + 被按动了! ) ;
}
}
当然如果你也可以单独为TextBox组件创建Click事件此时创建的事件语句可改为
myBoxClick += new SystemEventHandler ( thistxt _Click ) ;
下面是实现txt _Click ( )事件的程序代码
private void txt_Click ( object sender SystemEventArgs e )
{
TextBox currentButton = ( TextBox ) sender ;
MessageBoxShow ( currentButtonText + 被按动了!);
}
三. 本文中源程序已经程序运行的界面
下面这些图是程序运行
图程序中动态创建了组件
图单击创建的按钮的结果图
图单击创建的文本框的结果图
下面是实现上面结果的程序源代码
using System ;
using SystemDrawing ;
using SystemCollections ;
using SystemComponentModel ;
using SystemWindowsForms ;
using SystemData ;
namespace DynamicControls
{
public class Form : Form
{
private Button btnAdd ;
private SystemComponentModelContainer components = null ;
private Button txtAdd ;
//给产生的按钮定义一个数量计算器
private int counter ;
//给产生的按钮定义相对位置的纵坐标
private int locY ;
//给产生的文本框定义一个数量计算器
private int counter ;
//给产生的文本框定义相对位置的纵坐标
private int locY ;
public Form ( )
{
InitializeComponent ( ) ;
//初始化产生的按钮何文本框位置的纵坐标
locY = thisbtnAddLocationY ;
locY = thistxtAddLocationY ;
}
//清除在程序中使用到的资源
protected override void Dispose ( bool disposing )
{
if ( disposing )
{
if ( components != null )
{
componentsDispose ( ) ;
}
}
baseDispose ( disposing ) ;
}
private void InitializeComponent ( )
{
thisbtnAdd = new Button ( ) ;
thistxtAdd = new Button ( ) ;
thisSuspendLayout ( ) ;
thisbtnAddFlatStyle = FlatStylePopup ;
thisbtnAddLocation = new SystemDrawingPoint ( ) ;
thisbtnAddName = btnAdd ;
thisbtnAddTabIndex = ;
thisbtnAddText = 生成按钮! ;
thisbtnAddClick += new SystemEventHandler ( thisbtnAdd_Click ) ;
thistxtAddFlatStyle = FlatStylePopup ;
thistxtAddLocation = new SystemDrawingPoint ( ) ;
thistxtAddName = txtAdd ;
thistxtAddTabIndex = ;
thistxtAddText = 生成文本框! ;
thistxtAddClick += new SystemEventHandler ( thistxtAdd_Click ) ;
thisAutoScaleBaseSize = new SystemDrawingSize ( ) ;
thisClientSize = new SystemDrawingSize ( ) ;
thisControlsAdd ( btnAdd ) ;
thisControlsAdd ( txtAdd ) ;
thisName = Form ;
thisText = 在Visual C#中如何动态产生组件! ;
thisResumeLayout ( false ) ;
}
static void Main ( )
{
ApplicationRun ( new Form ( ) ) ;
}
private void btnAdd_Click ( object sender SystemEventArgs e )
{
//按钮数量计算器在每次按钮按动后加
counter += ;
//对要产生的按钮的纵坐标的相对位置是前一个产生按钮的相对位置的纵坐标加
locY += thisbtnAddHeight + ;
//创建一个新的Button组件
Button myButton = new Button ( ) ;
//设定他的名称和Text属性以及产生的位置
myButtonName = Button + counter ;
myButtonText = 按钮 + counter ;
myButtonLocation = new Point ( btnAddLocationX locY ) ;
//为产生的新的Button组件设定事件本文中为产生的按钮设定了三个事件
myButtonMouseEnter += new SystemEventHandler ( thisbtn_MouseEnter ) ;
myButtonMouseLeave += new SystemEventHandler ( thisbtn_MouseLeave ) ;
myButtonClick += new SystemEventHandler ( thisbtn_Click ) ;
//在窗体中显示此按钮
thisControlsAdd ( myButton ) ;
}
private void txtAdd_Click ( object sender SystemEventArgs e )
{
//文本框数量计算器在每次按钮按动后加
counter += ;
//对要产生的文本框的纵坐标的相对位置是前一个产生按钮的相对位置的纵坐标加
locY += thistxtAddHeight + ;
//创建一个新的TextBox组件
TextBox myBox = new TextBox ( ) ;
//设定他的名称和Text属性以及产生的位置
myBoxName = TextBox + counter ;
myBoxText = 文本框 + counter ;
myBoxLocation = new Point ( txtAddLocationX locY ) ;
//为产生的新的TextBox组件设定事件本文中为产生的文本框设定了一个事件
myBoxClick += new SystemEventHandler ( thisbtn_Click ) ;
//在窗体中显示此文本框
thisControlsAdd ( myBox ) ;
}
private void btn_MouseEnter ( object sender SystemEventArgs e )
{
//出箱
Button currentButton = ( Button ) sender ;
//设定按钮的背景色
currentButtonBackColor = ColorRed ;
}
private void btn_MouseLeave ( object sender SystemEventArgs e )
{
//出箱
Button currentButton = ( Button ) sender ;
currentButtonBackColor = ControlDefaultBackColor ;
}
private void btn_Click ( object sender SystemEventArgs e )
{
if ( senderGetType ( ) == typeof ( Button ) )
{
Button control = ( Button ) sender ;
MessageBoxShow ( controlText + 被按动了!);
}
else
{
TextBox control = ( TextBox ) sender ;
MessageBoxShow ( controlText + 被按动了! ) ;
}
}
}
}
四. 总结
通过上面介绍不难看出动态创建组件并不是一件很难的事情难就难在为这个组件创建事件上面因为这涉及到实值类型变量和参考类型变量的转换这就是所谓的装箱和出箱的问题当然在程序设计的时候你不仅可以创建那些可见的组件也可以创建那些不可见的组件具体的实现方法和本文中的方法类似