直播中
一. Boxing (裝箱)和Unboxing (出箱):
在用Visual C#動態(tài)創(chuàng)建組件的時(shí)候,要涉及到二種數(shù)據(jù)類型變量的轉(zhuǎn)換,這二種類型變量就是實(shí)值類型(Value Type)變量和參考類型(Reference Type)變量,而這種轉(zhuǎn)換過程在Visual C#中被稱為Boxing (裝箱)和Unboxing (出箱)。其中把實(shí)值類型變量轉(zhuǎn)換成參考類型變量就是Boxing (裝箱);把參考類型變量轉(zhuǎn)換成實(shí)值類型變量就是Unboxing (出箱)。那么什么是實(shí)值類型,說的簡單些,就是我們平常使用的整型、布爾型、枚舉型等,這些類型的變量就是實(shí)值類型變量了;所謂參考類型,在Visual C#中指的就是Object、Class、Interface、Delegate、String、Array等,他和實(shí)值類型最主要的不同之處就是,參考類型變量存放的是指向?qū)嶓w對象的指針,而實(shí)值類型變量卻是實(shí)實(shí)在在地實(shí)體對象。在本文介紹的程序中,主要涉及的是出箱。具體的處理方法,在下面有著具體介紹。
二. 本文中程序設(shè)計(jì)和運(yùn)行的環(huán)境:
?。?).微軟公司視窗2000服務(wù)器版
?。?)..Net FrameWork SDK Beta 2
三. 程序設(shè)計(jì)中的關(guān)鍵步驟以及解決方法:
文中軟件主要功能是用通過窗體上的二個(gè)按鈕來創(chuàng)建二個(gè)不同類型的WinForm組件--Button組件和TextBox組件,并在創(chuàng)建的同時(shí)為每一個(gè)組件的屬性賦值,給每一個(gè)創(chuàng)建的組件也創(chuàng)建了事件。
?。?).如何在窗體上創(chuàng)建Button組件:
其實(shí)用Visual C#創(chuàng)建一個(gè)組件是十分方便的,只用下列二行語句就可以完成了:
//創(chuàng)建一個(gè)新的Button組件
Button myButton = new Button ( ) ;
//在窗體中顯示此按鈕
this.Controls.Add ( myButton ) ;
但此時(shí)創(chuàng)建的這個(gè)Button組件沒有任何屬性,并且也沒有任何事件,在本文中介紹的程序中創(chuàng)建的Button組件,不僅有屬性也有事件,下列語句就是本文程序創(chuàng)建Button組件源代碼:
//按鈕數(shù)量計(jì)算器在每次按鈕按動后加"1"
counter += 1 ;
//對要產(chǎn)生的按鈕的縱坐標(biāo)的相對位置是前一個(gè)產(chǎn)生按鈕的相對位置的縱坐標(biāo)加"3"
locY += this.btnAdd.Height + 3 ;
//創(chuàng)建一個(gè)新的Button組件
Button myButton = new Button ( ) ;
//設(shè)定他的名稱和Text屬性,以及產(chǎn)生的相對位置
myButton.Name = "Button " + counter ;
myButton.Text = "按鈕 " + counter ;
myButton.Location = new Point ( btnAdd.Location.X , locY ) ;
//為產(chǎn)生的新的Button組件設(shè)定事件,本文中為產(chǎn)生的按鈕設(shè)定了三個(gè)事件
myButton.MouseEnter += new System.EventHandler ( this.btn_MouseEnter ) ;
myButton.MouseLeave += new System.EventHandler ( this.btn_MouseLeave ) ;
myButton.Click += new System.EventHandler ( this.btn_Click ) ;
//在窗體中顯示此按鈕
this.Controls.Add ( myButton ) ;
程序不僅為每一個(gè)組件的屬性都賦值,而且為每一個(gè)組件都創(chuàng)建了三個(gè)事件。細(xì)心的讀者可能已經(jīng)注意到,程序?yàn)槊恳粋€(gè)組件創(chuàng)建的事件的名稱都是一樣的。這樣就有一個(gè)問題,如何在這一樣的事件中,識別到底是哪個(gè)Button組件觸發(fā)了事件。
?。?).確定是哪個(gè)組件觸發(fā)了事件:
由于程序中為每一個(gè)創(chuàng)建的Button組件的事件都是一樣的,要想正確處理這些組件的事件,就需要在事件觸發(fā)的程序中判斷到底是哪個(gè)組件觸發(fā)了這個(gè)事件。這就需要用到上面所提出的裝箱和出箱。我們知道Sender對象是一個(gè)參考類型變量,他存放的是指向觸發(fā)當(dāng)前事件實(shí)體對象的指針。要把他給轉(zhuǎn)換成實(shí)值對象類型,通過下列語句就可以確定是哪個(gè)組件觸發(fā)了當(dāng)前事件:
private void btn_MouseEnter ( object sender , System.EventArgs e )
{
//出箱
Button currentButton = ( Button ) sender ;
//設(shè)定按鈕的背景色
currentButton.BackColor = Color.Red ;
}
其他事件可以仿照此事件的處理過程來處理。
?。?). 如何在窗體上創(chuàng)建TextBox組件:
創(chuàng)建TextBox組件的過程和創(chuàng)建Button組件過程相類似,只是在創(chuàng)建的組件類型上面有一點(diǎn)區(qū)別,具體實(shí)現(xiàn)語句如下:
//文本框數(shù)量計(jì)算器在每次按鈕按動后加"1"
counter01 += 1 ;
//對要產(chǎn)生的文本框的縱坐標(biāo)的相對位置是前一個(gè)產(chǎn)生按鈕的相對位置的縱坐標(biāo)加"3
locY1 += this.txtAdd.Height + 3 ;
//創(chuàng)建一個(gè)新的TextBox組件
TextBox myBox = new TextBox ( ) ;
//設(shè)定他的名稱和Text屬性,以及產(chǎn)生的位置
myBox.Name = "TextBox " + counter01 ;
myBox.Text = "文本框 " + counter01 ;
myBox.Location = new Point ( txtAdd.Location.X , locY1 ) ;
//為產(chǎn)生的新的TextBox組件設(shè)定事件,本文中為產(chǎn)生的文本框設(shè)定了一個(gè)事件
myBox.Click += new System.EventHandler ( this.btn_Click ) ;
//在窗體中顯示此文本框
this.Controls.Add ( myBox ) ;
此時(shí)細(xì)心的讀者又會發(fā)現(xiàn),為每一個(gè)TextBox組件創(chuàng)建Click事件和為Button組件創(chuàng)建的Click事件也是一樣的,這樣在Click事件中不僅要判斷是哪個(gè)組件觸發(fā)了事件,還要判斷是那種類型的組件觸發(fā)了事件,下面語句是實(shí)現(xiàn)這些判斷地具體方法:
private void btn_Click ( object sender , System.EventArgs e )
{
if ( sender.GetType ( ) == typeof ( Button ) )
{
Button control = ( Button ) sender ;
MessageBox.Show ( control.Text + "被按動了!");
}
else
{
TextBox control = ( TextBox ) sender ;
MessageBox.Show ( control.Text + "被按動了!" ) ;
}
}
當(dāng)然如果你也可以單獨(dú)為TextBox組件創(chuàng)建Click事件。此時(shí)創(chuàng)建的事件語句可改為:
myBox.Click += new System.EventHandler ( this.txt _Click ) ;
下面是實(shí)現(xiàn)txt _Click ( )事件的程序代碼:
private void txt_Click ( object sender , System.EventArgs e )
{
TextBox currentButton = ( TextBox ) sender ;
MessageBox.Show ( currentButton.Text + "被按動了!");
}
四. 本文中源程序已經(jīng)程序運(yùn)行的界面:
下面這些圖是程序運(yùn)行:
圖01:程序中動態(tài)創(chuàng)建了組件
圖02:單擊創(chuàng)建的按鈕的結(jié)果圖
圖03:單擊創(chuàng)建的文本框的結(jié)果圖
下面是實(shí)現(xiàn)上面結(jié)果的程序源代碼:
using System ;
using System.Drawing ;
using System.Collections ;
using System.ComponentModel ;
using System.Windows.Forms ;
using System.Data ;
namespace DynamicControls
{
public class Form1 : Form
{
private Button btnAdd ;
private System.ComponentModel.Container components = null ;
private Button txtAdd ;
//給產(chǎn)生的按鈕定義一個(gè)數(shù)量計(jì)算器
private int counter ;
//給產(chǎn)生的按鈕定義相對位置的縱坐標(biāo)
private int locY ;
//給產(chǎn)生的文本框定義一個(gè)數(shù)量計(jì)算器
private int counter01 ;
//給產(chǎn)生的文本框定義相對位置的縱坐標(biāo)
private int locY1 ;
public Form1 ( )
{
InitializeComponent ( ) ;
//初始化產(chǎn)生的按鈕何文本框位置的縱坐標(biāo)
locY = this.btnAdd.Location.Y ;
locY1 = this.txtAdd.Location.Y ;
}
//清除在程序中使用到的資源
protected override void Dispose ( bool disposing )
{
if ( disposing )
{
if ( components != null )
{
components.Dispose ( ) ;
}
}
base.Dispose ( disposing ) ;
}
private void InitializeComponent ( )
{
this.btnAdd = new Button ( ) ;
this.txtAdd = new Button ( ) ;
this.SuspendLayout ( ) ;
this.btnAdd.FlatStyle = FlatStyle.Popup ;
this.btnAdd.Location = new System.Drawing.Point ( 8 , 16 ) ;
this.btnAdd.Name = "btnAdd" ;
this.btnAdd.TabIndex = 0 ;
this.btnAdd.Text = "生成按鈕!" ;
this.btnAdd.Click += new System.EventHandler ( this.btnAdd_Click ) ;
this.txtAdd.FlatStyle = FlatStyle.Popup ;
this.txtAdd.Location = new System.Drawing.Point ( 108 , 16 ) ;
this.txtAdd.Name = "txtAdd" ;
this.txtAdd.TabIndex = 1 ;
this.txtAdd.Text = "生成文本框!" ;
this.txtAdd.Click += new System.EventHandler ( this.txtAdd_Click ) ;
this.AutoScaleBaseSize = new System.Drawing.Size ( 5 , 13 ) ;
this.ClientSize = new System.Drawing.Size ( 292 , 273 ) ;
this.Controls.Add ( btnAdd ) ;
this.Controls.Add ( txtAdd ) ;
this.Name = "Form1" ;
this.Text = "在Visual C#中如何動態(tài)產(chǎn)生組件!" ;
this.ResumeLayout ( false ) ;
}
static void Main ( )
{
Application.Run ( new Form1 ( ) ) ;
}
private void btnAdd_Click ( object sender , System.EventArgs e )
{
//按鈕數(shù)量計(jì)算器在每次按鈕按動后加"1"
counter += 1 ;
//對要產(chǎn)生的按鈕的縱坐標(biāo)的相對位置是前一個(gè)產(chǎn)生按鈕的相對位置的縱坐標(biāo)加"3"
locY += this.btnAdd.Height + 3 ;
//創(chuàng)建一個(gè)新的Button組件
Button myButton = new Button ( ) ;
//設(shè)定他的名稱和Text屬性,以及產(chǎn)生的位置
myButton.Name = "Button " + counter ;
myButton.Text = "按鈕 " + counter ;
myButton.Location = new Point ( btnAdd.Location.X , locY ) ;
//為產(chǎn)生的新的Button組件設(shè)定事件,本文中為產(chǎn)生的按鈕設(shè)定了三個(gè)事件
myButton.MouseEnter += new System.EventHandler ( this.btn_MouseEnter ) ;
myButton.MouseLeave += new System.EventHandler ( this.btn_MouseLeave ) ;
myButton.Click += new System.EventHandler ( this.btn_Click ) ;
//在窗體中顯示此按鈕
this.Controls.Add ( myButton ) ;
}
private void txtAdd_Click ( object sender , System.EventArgs e )
{
//文本框數(shù)量計(jì)算器在每次按鈕按動后加"1"
counter01 += 1 ;
//對要產(chǎn)生的文本框的縱坐標(biāo)的相對位置是前一個(gè)產(chǎn)生按鈕的相對位置的縱坐標(biāo)加"3
locY1 += this.txtAdd.Height + 3 ;
//創(chuàng)建一個(gè)新的TextBox組件
TextBox myBox = new TextBox ( ) ;
//設(shè)定他的名稱和Text屬性,以及產(chǎn)生的位置
myBox.Name = "TextBox " + counter01 ;
myBox.Text = "文本框 " + counter01 ;
myBox.Location = new Point ( txtAdd.Location.X , locY1 ) ;
//為產(chǎn)生的新的TextBox組件設(shè)定事件,本文中為產(chǎn)生的文本框設(shè)定了一個(gè)事件
myBox.Click += new System.EventHandler ( this.btn_Click ) ;
//在窗體中顯示此文本框
this.Controls.Add ( myBox ) ;
}
private void btn_MouseEnter ( object sender , System.EventArgs e )
{
//出箱
Button currentButton = ( Button ) sender ;
//設(shè)定按鈕的背景色
currentButton.BackColor = Color.Red ;
}
private void btn_MouseLeave ( object sender , System.EventArgs e )
{
//出箱
Button currentButton = ( Button ) sender ;
currentButton.BackColor = Control.DefaultBackColor ;
}
private void btn_Click ( object sender , System.EventArgs e )
{
if ( sender.GetType ( ) == typeof ( Button ) )
{
Button control = ( Button ) sender ;
MessageBox.Show ( control.Text + "被按動了!");
}
else
{
TextBox control = ( TextBox ) sender ;
MessageBox.Show ( control.Text + "被按動了!" ) ;
}
}
}
}