Visual C#動態產生控制項

來源:互聯網
上載者:User

以前在用Delphi寫程式的時候,總不喜歡在表單上排放很多組件,這一方面有點不美觀,並且在偵錯工具時候,也不是十分方便。通常在寫程式的時候,當要用到某些組件,採用的方法一般都是動態建立,用完以後就釋放掉。Visual C#在程式啟動並執行時候也可以動態建立組件,下面就結合一個程式例子來具體介紹如何用Visual C#動態產生組件。首先讓我們瞭解一下,在動態建立組件的過程中要用到的一些概論和理論。

一. Boxing (裝箱)和Unboxing (出箱):

在用Visual C#動態建立組件的時候,要涉及到二種資料類型變數的轉換,這二種類型變數就是實實值型別(Value Type)變數和參考類型(Reference Type)變數,而這種轉換過程在Visual C#中被稱為Boxing (裝箱)和Unboxing (出箱)。其中把實實值型別變數轉換成參考類型變數就是Boxing (裝箱);把參考類型變數轉換成實實值型別變數就是Unboxing (出箱)。那麼什麼是實實值型別,說的簡單些,就是我們平常使用的整型、布爾型、枚舉型等,這些類型的變數就是實實值型別變數了;所謂參考類型,在Visual C#中指的就是Object、Class、Interface、Delegate、String、Array等,他和實實值型別最主要的不同之處就是,參考類型變數存放的是指向實體物件的指標,而實實值型別變數卻是實實在在地實體物件。在本文介紹的程式中,主要涉及的是出箱。具體的處理方法,在下面有著具體介紹。

二. 本文中程式設計和啟動並執行環境:

(1).微軟公司視窗2000伺服器版

(2)..Net FrameWork SDK Beta 2

三. 程式設計中的關鍵步驟以及解決方案:

文中軟體主要功能是用通過表單上的二個按鈕來建立二個不同類型的WinForm組件--Button組件和TextBox組件,並在建立的同時為每一個組件的屬性賦值,給每一個建立的組件也建立了事件。

(1).如何在表單上建立Button組件:

其實用Visual C#建立一個組件是十分方便的,只用下列二行語句就可以完成了:

//建立一個新的Button組件
Button myButton = new Button ( ) ;
//在表單中顯示此按鈕
this.Controls.Add ( myButton ) ;
但此時建立的這個Button組件沒有任何屬性,並且也沒有任何事件,在本文中介紹的程式中建立的Button組件,不僅有屬性也有事件,下列語句就是本文程式建立Button組件原始碼:
//按鈕數量計算機在每次按鈕按動後加"1"
counter += 1 ;
//對要產生的按鈕的縱座標的相對位置是前一個產生按鈕的相對位置的縱座標加"3"
locY += this.btnAdd.Height + 3 ;
//建立一個新的Button組件
Button myButton = new Button ( ) ;
//設定他的名稱和Text屬性,以及產生的相對位置
myButton.Name = "Button " + counter ;
myButton.Text = "按鈕 " + counter ;
myButton.Location = new Point ( btnAdd.Location.X , locY ) ;
//為產生的新的Button組件設定事件,本文中為產生的按鈕設定了三個事件
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 ) ;

程式不僅為每一個組件的屬性都賦值,而且為每一個組件都建立了三個事件。細心的讀者可能已經注意到,程式為每一個組件建立的事件的名稱都是一樣的。這樣就有一個問題,如何在這一樣的事件中,識別到底是哪個Button組件觸發了事件。

(2).確定是哪個組件觸發了事件:

由於程式中為每一個建立的Button組件的事件都是一樣的,要想正確處理這些組件的事件,就需要在事件觸發的程式中判斷到底是哪個組件觸發了這個事件。這就需要用到上面所提出的裝箱和出箱。我們知道Sender對象是一個參考類型變數,他存放的是指向觸發當前事件實體物件的指標。要把他給轉換成實值物件類型,通過下列語句就可以確定是哪個組件觸發了當前事件:

private void btn_MouseEnter ( object sender , System.EventArgs e )
{
//出箱
Button currentButton = ( Button ) sender ;
//設定按鈕的背景色
currentButton.BackColor = Color.Red ;
}

其他事件可以仿照此事件的處理過程來處理。

(3). 如何在表單上建立TextBox組件:

建立TextBox組件的過程和建立Button組件過程相類似,只是在建立的組件類型上面有一點區別,具體實現語句如下:

//文字框數量計算機在每次按鈕按動後加"1"
counter01 += 1 ;
//對要產生的文字框的縱座標的相對位置是前一個產生按鈕的相對位置的縱座標加"3
locY1 += this.txtAdd.Height + 3 ;
//建立一個新的TextBox組件
TextBox myBox = new TextBox ( ) ;
//設定他的名稱和Text屬性,以及產生的位置
myBox.Name = "TextBox " + counter01 ;
myBox.Text = "文字框 " + counter01 ;
myBox.Location = new Point ( txtAdd.Location.X , locY1 ) ;
//為產生的新的TextBox組件設定事件,本文中為產生的文字框設定了一個事件
myBox.Click += new System.EventHandler ( this.btn_Click ) ;
//在表單中顯示此文字框
this.Controls.Add ( myBox ) ;

此時細心的讀者又會發現,為每一個TextBox組件建立Click事件和為Button組件建立的Click事件也是一樣的,這樣在Click事件中不僅要判斷是哪個組件觸發了事件,還要判斷是那種類型的組件觸發了事件,下面語句是實現這些判斷地具體方法:

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 + "被按動了!" ) ;
}
}

當然如果你也可以單獨為TextBox組件建立Click事件。此時建立的事件語句可改為:

myBox.Click += new System.EventHandler ( this.txt _Click ) ;

下面是實現txt _Click ( )事件的程式碼:

private void txt_Click ( object sender , System.EventArgs e )
{
TextBox currentButton = ( TextBox ) sender ;
MessageBox.Show ( currentButton.Text + "被按動了!");

下面是實現上面結果的程式原始碼:

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 ;
//給產生的按鈕定義一個數量計算機
private int counter ;
//給產生的按鈕定義相對位置的縱座標
private int locY ;
//給產生的文字框定義一個數量計算機
private int counter01 ;
//給產生的文字框定義相對位置的縱座標
private int locY1 ;
public Form1 ( )
{
InitializeComponent ( ) ;
//初始化產生的按鈕何文字框位置的縱座標
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#中如何動態產生組件!" ;
this.ResumeLayout ( false ) ;

}
static void Main ( )
{
Application.Run ( new Form1 ( ) ) ;
}
private void btnAdd_Click ( object sender , System.EventArgs e )
{
//按鈕數量計算機在每次按鈕按動後加"1"
counter += 1 ;
//對要產生的按鈕的縱座標的相對位置是前一個產生按鈕的相對位置的縱座標加"3"
locY += this.btnAdd.Height + 3 ;
//建立一個新的Button組件
Button myButton = new Button ( ) ;
//設定他的名稱和Text屬性,以及產生的位置
myButton.Name = "Button " + counter ;
myButton.Text = "按鈕 " + counter ;
myButton.Location = new Point ( btnAdd.Location.X , locY ) ;

//為產生的新的Button組件設定事件,本文中為產生的按鈕設定了三個事件
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 )
{
//文字框數量計算機在每次按鈕按動後加"1"
counter01 += 1 ;
//對要產生的文字框的縱座標的相對位置是前一個產生按鈕的相對位置的縱座標加"3
locY1 += this.txtAdd.Height + 3 ;
//建立一個新的TextBox組件
TextBox myBox = new TextBox ( ) ;
//設定他的名稱和Text屬性,以及產生的位置
myBox.Name = "TextBox " + counter01 ;
myBox.Text = "文字框 " + counter01 ;
myBox.Location = new Point ( txtAdd.Location.X , locY1 ) ;
//為產生的新的TextBox組件設定事件,本文中為產生的文字框設定了一個事件
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 + "被按動了!");
}
else
{
TextBox control = ( TextBox ) sender ;
MessageBox.Show ( control.Text + "被按動了!" ) ;
}
}

}
}

五. 總結:

通過上面介紹,不難看出,動態建立組件並不是一件很難的事情,難就難在為這個組件建立事件上面,因為這涉及到實實值型別變數和參考類型變數的轉換,這就是所謂的裝箱和出箱的問題。當然在程式設計的時候,你不僅可以建立那些可見的組件,也可以建立那些不可見的組件,具體的實現方法和本文中的方法類似。

轉自:http://www.yaosansi.com/post/116.html

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.