| 以前在用Delphi寫(xiě)程序的時(shí)候,總不喜歡在窗體上排放很多組件,這一方面有點(diǎn)不美觀(guān),并且在調試程序時(shí)候,也不是十分方便。通常在寫(xiě)程序的時(shí)候,當要用到某些組件,采用的方法一般都是動(dòng)態(tài)創(chuàng )建,用完以后就釋放掉。Visual C#在程序運行的時(shí)候也可以動(dòng)態(tài)創(chuàng )建組件,下面就結合一個(gè)程序例子來(lái)具體介紹如何用Visual C#動(dòng)態(tài)生成組件。首先讓我們了解一下,在動(dòng)態(tài)創(chuàng )建組件的過(guò)程中要用到的一些概論和理論。 一. Boxing (裝箱)和Unboxing (出箱): 在用Visual C#動(dòng)態(tài)創(chuàng )建組件的時(shí)候,要涉及到二種數據類(lèi)型變量的轉換,這二種類(lèi)型變量就是實(shí)值類(lèi)型(Value Type)變量和參考類(lèi)型(Reference Type)變量,而這種轉換過(guò)程在Visual C#中被稱(chēng)為Boxing (裝箱)和Unboxing (出箱)。其中把實(shí)值類(lèi)型變量轉換成參考類(lèi)型變量就是Boxing (裝箱);把參考類(lèi)型變量轉換成實(shí)值類(lèi)型變量就是Unboxing (出箱)。那么什么是實(shí)值類(lèi)型,說(shuō)的簡(jiǎn)單些,就是我們平常使用的整型、布爾型、枚舉型等,這些類(lèi)型的變量就是實(shí)值類(lèi)型變量了;所謂參考類(lèi)型,在Visual C#中指的就是Object、Class、Interface、Delegate、String、Array等,他和實(shí)值類(lèi)型最主要的不同之處就是,參考類(lèi)型變量存放的是指向實(shí)體對象的指針,而實(shí)值類(lèi)型變量卻是實(shí)實(shí)在在地實(shí)體對象。在本文介紹的程序中,主要涉及的是出箱。具體的處理方法,在下面有著(zhù)具體介紹。 二. 本文中程序設計和運行的環(huán)境: (1).微軟公司視窗2000服務(wù)器版 (2)..Net FrameWork SDK Beta 2 三. 程序設計中的關(guān)鍵步驟以及解決方法: 文中軟件主要功能是用通過(guò)窗體上的二個(gè)按鈕來(lái)創(chuàng )建二個(gè)不同類(lèi)型的WinForm組件--Button組件和TextBox組件,并在創(chuàng )建的同時(shí)為每一個(gè)組件的屬性賦值,給每一個(gè)創(chuàng )建的組件也創(chuàng )建了事件。 (1).如何在窗體上創(chuàng )建Button組件: 其實(shí)用Visual C#創(chuàng )建一個(gè)組件是十分方便的,只用下列二行語(yǔ)句就可以完成了: //創(chuàng )建一個(gè)新的Button組件 Button myButton = new Button ( ) ; //在窗體中顯示此按鈕 this.Controls.Add ( myButton ) ; 但此時(shí)創(chuàng )建的這個(gè)Button組件沒(méi)有任何屬性,并且也沒(méi)有任何事件,在本文中介紹的程序中創(chuàng )建的Button組件,不僅有屬性也有事件,下列語(yǔ)句就是本文程序創(chuàng )建Button組件源代碼: //按鈕數量計算器在每次按鈕按動(dòng)后加"1" counter += 1 ; //對要產(chǎn)生的按鈕的縱坐標的相對位置是前一個(gè)產(chǎn)生按鈕的相對位置的縱坐標加"3" locY += this.btnAdd.Height + 3 ; //創(chuàng )建一個(gè)新的Button組件 Button myButton = new Button ( ) ; //設定他的名稱(chēng)和Text屬性,以及產(chǎn)生的相對位置 myButton.Name = "Button " + counter ; myButton.Text = "按鈕 " + counter ; myButton.Location = new Point ( btnAdd.Location.X , locY ) ; //為產(chǎn)生的新的Button組件設定事件,本文中為產(chǎn)生的按鈕設定了三個(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è)事件。細心的讀者可能已經(jīng)注意到,程序為每一個(gè)組件創(chuàng )建的事件的名稱(chēng)都是一樣的。這樣就有一個(gè)問(wèn)題,如何在這一樣的事件中,識別到底是哪個(gè)Button組件觸發(fā)了事件。 (2).確定是哪個(gè)組件觸發(fā)了事件: 由于程序中為每一個(gè)創(chuàng )建的Button組件的事件都是一樣的,要想正確處理這些組件的事件,就需要在事件觸發(fā)的程序中判斷到底是哪個(gè)組件觸發(fā)了這個(gè)事件。這就需要用到上面所提出的裝箱和出箱。我們知道Sender對象是一個(gè)參考類(lèi)型變量,他存放的是指向觸發(fā)當前事件實(shí)體對象的指針。要把他給轉換成實(shí)值對象類(lèi)型,通過(guò)下列語(yǔ)句就可以確定是哪個(gè)組件觸發(fā)了當前事件: private void btn_MouseEnter ( object sender , System.EventArgs e ) { //出箱 Button currentButton = ( Button ) sender ; //設定按鈕的背景色 currentButton.BackColor = Color.Red ; } 其他事件可以仿照此事件的處理過(guò)程來(lái)處理。 (3). 如何在窗體上創(chuàng )建TextBox組件: 創(chuàng )建TextBox組件的過(guò)程和創(chuàng )建Button組件過(guò)程相類(lèi)似,只是在創(chuàng )建的組件類(lèi)型上面有一點(diǎn)區別,具體實(shí)現語(yǔ)句如下: //文本框數量計算器在每次按鈕按動(dòng)后加"1" counter01 += 1 ; //對要產(chǎn)生的文本框的縱坐標的相對位置是前一個(gè)產(chǎn)生按鈕的相對位置的縱坐標加"3 locY1 += this.txtAdd.Height + 3 ; //創(chuàng )建一個(gè)新的TextBox組件 TextBox myBox = new TextBox ( ) ; //設定他的名稱(chēng)和Text屬性,以及產(chǎn)生的位置 myBox.Name = "TextBox " + counter01 ; myBox.Text = "文本框 " + counter01 ; myBox.Location = new Point ( txtAdd.Location.X , locY1 ) ; //為產(chǎn)生的新的TextBox組件設定事件,本文中為產(chǎn)生的文本框設定了一個(gè)事件 myBox.Click += new System.EventHandler ( this.btn_Click ) ; //在窗體中顯示此文本框 this.Controls.Add ( myBox ) ; 此時(shí)細心的讀者又會(huì )發(fā)現,為每一個(gè)TextBox組件創(chuàng )建Click事件和為Button組件創(chuàng )建的Click事件也是一樣的,這樣在Click事件中不僅要判斷是哪個(gè)組件觸發(fā)了事件,還要判斷是那種類(lèi)型的組件觸發(fā)了事件,下面語(yǔ)句是實(shí)現這些判斷地具體方法: private void btn_Click ( object sender , System.EventArgs e ) { if ( sender.GetType ( ) == typeof ( Button ) ) { Button control = ( Button ) sender ; MessageBox.Show ( control.Text + "被按動(dòng)了!"); } else { TextBox control = ( TextBox ) sender ; MessageBox.Show ( control.Text + "被按動(dòng)了!" ) ; } } 當然如果你也可以單獨為T(mén)extBox組件創(chuàng )建Click事件。此時(shí)創(chuàng )建的事件語(yǔ)句可改為: myBox.Click += new System.EventHandler ( this.txt _Click ) ; 下面是實(shí)現txt _Click ( )事件的程序代碼: private void txt_Click ( object sender , System.EventArgs e ) { TextBox currentButton = ( TextBox ) sender ; MessageBox.Show ( currentButton.Text + "被按動(dòng)了!"); } 四. 本文中源程序已經(jīng)程序運行的界面: 下面這些圖是程序運行: 圖01:程序中動(dòng)態(tài)創(chuàng )建了組件
圖02:?jiǎn)螕魟?chuàng )建的按鈕的結果圖 圖03:?jiǎn)螕魟?chuàng )建的文本框的結果圖
下面是實(shí)現上面結果的程序源代碼: 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è)數量計算器 private int counter ; //給產(chǎn)生的按鈕定義相對位置的縱坐標 private int locY ; //給產(chǎn)生的文本框定義一個(gè)數量計算器 private int counter01 ; //給產(chǎn)生的文本框定義相對位置的縱坐標 private int locY1 ; public Form1 ( ) { InitializeComponent ( ) ; //初始化產(chǎn)生的按鈕何文本框位置的縱坐標 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#中如何動(dòng)態(tài)產(chǎn)生組件!" ; this.ResumeLayout ( false ) ; } static void Main ( ) { Application.Run ( new Form1 ( ) ) ; } private void btnAdd_Click ( object sender , System.EventArgs e ) { //按鈕數量計算器在每次按鈕按動(dòng)后加"1" counter += 1 ; //對要產(chǎn)生的按鈕的縱坐標的相對位置是前一個(gè)產(chǎn)生按鈕的相對位置的縱坐標加"3" locY += this.btnAdd.Height + 3 ; //創(chuàng )建一個(gè)新的Button組件 Button myButton = new Button ( ) ; //設定他的名稱(chēng)和Text屬性,以及產(chǎn)生的位置 myButton.Name = "Button " + counter ; myButton.Text = "按鈕 " + counter ; myButton.Location = new Point ( btnAdd.Location.X , locY ) ; //為產(chǎn)生的新的Button組件設定事件,本文中為產(chǎn)生的按鈕設定了三個(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 ) { //文本框數量計算器在每次按鈕按動(dòng)后加"1" counter01 += 1 ; //對要產(chǎn)生的文本框的縱坐標的相對位置是前一個(gè)產(chǎn)生按鈕的相對位置的縱坐標加"3 locY1 += this.txtAdd.Height + 3 ; //創(chuàng )建一個(gè)新的TextBox組件 TextBox myBox = new TextBox ( ) ; //設定他的名稱(chēng)和Text屬性,以及產(chǎn)生的位置 myBox.Name = "TextBox " + counter01 ; myBox.Text = "文本框 " + counter01 ; myBox.Location = new Point ( txtAdd.Location.X , locY1 ) ; //為產(chǎn)生的新的TextBox組件設定事件,本文中為產(chǎn)生的文本框設定了一個(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 ; //設定按鈕的背景色 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 + "被按動(dòng)了!"); } else { TextBox control = ( TextBox ) sender ; MessageBox.Show ( control.Text + "被按動(dòng)了!" ) ; } } } } |