C#.NET中動態添加與刪除控制項
介紹
數組為共用公用功能的一組控制項一起工作提供了便捷的途徑。例如,一組控制項可能用於顯示相關的資料,或者在被點擊時提供相關的行為。C#本身並不支援控制項數組的建立,但是你可以通過編程複製控制項數組的所有功能。本文介紹複製控制項數組功能的簡單組件的建立。
控制項數組的主要用處有:
1,使用相同的名稱與索引訪問一組控制項,允許用編號檢索和設定資料項目並且在整個數組中重複。這個功能可以使用下面的代碼實現。
虛擬碼
myControl[myIndex].MyProperty = myValue;
myControl[myIndex + 1].MyMethod
2,多個對象使用同一個事件處理常式(event handler)處理事件,在這些事件中檢索和使用索引,代碼如下:
虛擬碼
private void myControl_Click(System.Object sender, System.EventArgs e)
{
Messagebox.Show("You have clicked MyControl number " +
myControl.Index);
}
3,在運行時動態添加或者刪除控制項,代碼如下:
虛擬碼
for (int i = 1; i < 6; i++)
{
//插入代碼來建立控制項並給屬性賦值
}
C#允許你複製與控制項數組相關的一些功能。例如,你能使用委託把多個對象的事件綁定到一個事件處理常式。但是,如果把這些功能合并到一個動態、容易管理的組件中更加簡便。本文將建立有下面特性的組件:
· 建立索引和排序控制項的集合。將使用按鈕集合來示範。
· 一個事件處理常式來處理衍生的按鈕的點擊事件。
· 使用索引引用控制項和成員的代碼。
· 給表單動態添加和刪除控制項的代碼。
建立項目
在本節中將建立並命名一個項目,並給該項目添加一個類。該類將封裝實現控制項數組的代碼。
1、選擇File-> New-> Project菜單開啟New Project對話方塊。
2、從Visual C#項目列表中選擇Windows Application項目模版,在Name框中輸入ButtonArrayProject。
3、選擇File-> Save All儲存項目。
實現一個集合
ButtonArray類會處理通過一個集合的實現來儲存和組織控制項數組的事務。集合是包含索引物件變數列表的對象,也包含add、remove等方法和其它的操作對象。本節中將建立一個繼承自System.Collections.CollectionBase(.NET架構組件中提供必要的集合功能的類)的類,並實現提供必要功能的方法。
建立繼承類的過程:
1、從Project菜單中選擇Add Class。
2、根據情況把類命名為ButtonArray.cs。類的代碼編輯器將開啟。
3、在類的聲明中,指定它繼承自.NET架構組件的System.Collections.CollectionBase類。
public class ButtonArray : System.Collections.CollectionBase
{
// 省略了設計者增加的代碼
}
System.Collections.CollectionBase類為集合提供了很多必要的功能。其中包括一個跟蹤集合中對象的List對象,維護集合中當前對象數量的Count屬性,允許刪除特定位置索引的對象的RemoveAt方法。在實現控制項數組集合時會使用到它們。
因為每個控制項數組與一個表單關聯,索引必須添加一個欄位來儲存該表單的引用。通過建立私人的、唯讀欄位來儲存引用,可以保證每個控制項數組組件只與以一個表單關聯。
為組件建立私人、唯讀欄位
立即給類聲明添加下面的代碼:
private readonly System.Windows.Forms.Form HostForm;
在集合中實現的第一個方法是AddNewButton。該方法建立一個新的按鈕控制項並把它添加到目標表單。你也可以使用該方法為新按鈕設定初始屬性。
實現AddNewButton方法
在ButtonArray類的代碼編輯器中輸入下面的代碼:
public System.Windows.Forms.Button AddNewButton()
{
//為Button類建立新的執行個體
System.Windows.Forms.Button aButton = new
System.Windows.Forms.Button();
//將該按鈕添加到集合的內部列表
this.List.Add(aButton);
//把控制項集合中的按鈕添加到被HostForm欄位引用的表單
HostForm.Controls.Add(aButton);
//設定該按鈕對象的初始屬性
aButton.Top = Count * 25;
aButton.Left = 100;
aButton.Tag = this.Count;
aButton.Text = "Button " + this.Count.ToString();
return aButton;
}
上面的方法的功能是:
1、建立一個新按鈕。
2、把它添加到內部列表和HostForm引用的表單的控制項集合。
3、設定初始屬性,包括設定Tag屬性來索引該按鈕。你可以在這一段中添加代碼為控制項設定更多的屬性。
4、返回新按鈕,這樣它就能立即被修改並指定給其它的對象引用。
你必須建立一個建構函式(組件被初始化時啟動並執行方法),當控制項數組類的一個新執行個體被建立時,它用來設定HostForm欄位的值並把新按鈕添加到表單。可以使用下面的方式達到這個目的。
建立建構函式
為類建立建構函式。
// 使用下面的建構函式代替預設的建構函式
public ButtonArray(System.Windows.Forms.Form host)
{
HostForm = host;
this.AddNewButton();
}
建構函式需要一個參數,即放置按鈕數組的表單。它把該值指定給HostForm欄位,接著類的AddNewButton方法給表單添加一個新按鈕。
暴露控制項數組
現在已經建立了建立和跟蹤數組中控制項的途徑,但是還必須把它們暴露給開發人員。可以通過屬性實現這個功能。我們將建立一個預設索引器基於特定按鈕的索引返回它的引用。這樣你就能編程使用典型控制項數組中的MyButtonArray(myIndex)文法了。
建立預設屬性
給組件添加下面的代碼:
public System.Windows.Forms.Button this [int Index]
{
get
{
return (System.Windows.Forms.Button) this.List[Index];
}
}
實現Remove方法
現在已經建立了暴露數組中按鈕的屬性,可以建立從數組中刪除按鈕的機制了。為了從數組中刪除一個按鈕,必須從集合的內部List對象和表單的Controls集合中刪除它。
給組件添加下面的方法:
public void Remove()
{
//檢查以確保有按鈕可以刪除
if (this.Count > 0)
{
' 從主表單上的控制項集合的數組按鈕數組中刪除最後一個
' 注意在訪問數組時使用了預設屬性
HostForm.Controls.Remove(this[this.Count -1]);
this.List.RemoveAt(this.Count -1);
}
}
建立公用事件處理常式
最後一步是為控制項數組建立事件處理常式來處理公用的事件。在示範中,將為按鈕的點擊事件建立一個方法,接著添加代碼把該事件與事件處理常式關聯。
建立公用事件處理常式
給組件添加下面的方法:
public void ClickHandler(Object sender, System.EventArgs e)
{
System.Windows.Forms.MessageBox.Show("You have clicked button " +
((System.Windows.Forms.Button) sender).Tag.ToString());
}
該方法通過檢索儲存在按鈕的Tag屬性的索引,顯示一個訊息框表明哪個按鈕被點擊了。該方法的參數與被處理事件的相同,對於事件處理常式是必要的。你也必須把該事件與事件處理常式關聯。
把該事件與事件處理常式關聯
給AddNewButton方法添加下面的代碼:
aButton.Click += new System.EventHandler(ClickHandler);
測試該項目
現在組件已經完成了,需要建立一個應用程式來測試該組件。
建立測試應用程式
1、在解決方案管理器中,右鍵點擊Form1並從快顯功能表中選擇View Designer。
Form1的設計器被開啟了。
2、給表單添加兩個按鈕。
3、把這些按鈕的位置調整到表單的右側。
4、設定這些按鈕的屬性:
按鈕 Name Text
Button1 btnAdd Add Button
Button2 btnRemove Remove Button
5、在解決方案管理器中,右鍵點擊Form1並從快顯功能表中選擇View Code。
Form1的代碼編輯器被開啟了。
6、在Form1的類聲明中,聲明下面的控制項數組對象:
//聲明新的ButtonArray對象
ButtonArray MyControlArray;
7、在表單的建構函式中,在方法結尾前添加下面的代碼:
MyControlArray = new ButtonArray(this);
該語句建立了一個新的ButtonArray對象。它的參數this指向建立新ButtonArray的表單,將成為放置按鈕數組的表單。
8、在解決方案管理器中,右鍵點擊Form1並從快顯功能表中選擇View Designer。
9、在設計器中雙擊btnAdd來開啟btnAdd_Click事件的代碼編輯器。
10、在方法btnAdd_Click中添加代碼調用MyControlArray的AddNewButton方法:
//調用MyControlArray的AddNewButton方法
MyControlArray.AddNewButton();
//改變Button 0的BackColor屬性
MyControlArray[0].BackColor = System.Drawing.Color.Red;
11、在解決方案管理器中,右鍵點擊Form1並從快顯功能表中選擇View Designer。
12、在設計器中雙擊btnRemove來開啟btnRemove_Click事件的代碼編輯器。
13、在btnRemove_Click方法中添加下面的代碼:
// 調用MyControlArray的Remove方法
MyControlArray.Remove();
14、儲存項目
測試該項目 www.w3sky.com
1、從Debug菜單中選擇Start。
Form1表單被開啟,上面有三個按鈕,標籤分別是Add Button、Remove Button和Button 1。
2、點擊Button 1。
顯示了一個訊息框,訊息框正確地顯示了索引。
3、點擊幾次Add Button按鈕。
每次點擊會給表單添加一個新按鈕。點擊任何一個新按鈕將導致一個正確顯示該按鈕索引的訊息框。注意Button 0的顏色改變為紅色,是btnAdd_Click事件中下面一行的結果:
MyControlArray(0).BackColor = System.Drawing.Color.Red
4、點擊幾次Remove Button按鈕。
每次點擊時從表單上刪除一個按鈕。
5、點擊Remove Button按鈕直到表單右側的所有按鈕都被刪除為止。
6、再次點擊Add Button按鈕。
按鈕再次添加到表單並且索引的編號正確。
結論
本文示範了怎樣建立封裝控制項數組功能的組件。你可以看到怎樣建立方法來動態地給表單添加和刪除控制項,怎樣通過預設屬性或者索引器暴露對象。上面的代碼已經實現了所有的功能,還可以通過為組件編寫自訂代碼來擴充控制項數組。
代碼:
form1.cs
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
namespace DAddControl
{
/// <summary>
/// Form1 的摘要說明。
/// </summary>
public class Form1 : System.Windows.Forms.Form
{
private System.Windows.Forms.Button btnAdd;
private System.Windows.Forms.Button btnRemove;
ButtonArray MyControlArray;
/// <summary>
/// 必需的設計器變數。
/// </summary>
private System.ComponentModel.Container components = null;
public Form1()
{
//
// Windows 表單設計器支援所必需的
//
InitializeComponent();
//
// TODO: 在 InitializeComponent 調用後添加任何建構函式代碼
//
MyControlArray = new ButtonArray(this);
}
/// <summary>
/// 清理所有正在使用的資源。
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
#region Windows 表單設計器產生的程式碼
/// <summary>
/// 設計器支援所需的方法 - 不要使用代碼編輯器修改
/// 此方法的內容。
/// </summary>
private void InitializeComponent()
{
this.btnAdd = new System.Windows.Forms.Button();
this.btnRemove = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// btnAdd
//
this.btnAdd.Location = new System.Drawing.Point(216, 0);
this.btnAdd.Name = "btnAdd";
this.btnAdd.TabIndex = 0;
this.btnAdd.Text = "Add Button";
this.btnAdd.Click += new System.EventHandler(this.btnAdd_Click);
//
// btnRemove
//
this.btnRemove.Location = new System.Drawing.Point(216, 240);
this.btnRemove.Name = "btnRemove";
this.btnRemove.TabIndex = 1;
this.btnRemove.Text = "Remove Button";
this.btnRemove.Click += new System.EventHandler(this.btnRemove_Click);
//
// Form1
//
this.AutoScaleBaseSize = new System.Drawing.Size(6, 14);
this.ClientSize = new System.Drawing.Size(292, 266);
this.Controls.Add(this.btnRemove);
this.Controls.Add(this.btnAdd);
this.Name = "Form1";
this.Text = "Form1";
this.ResumeLayout(false);
}
#endregion
/// <summary>
/// 應用程式的主進入點。
/// </summary>
[STAThread]
static void Main()
{
Application.Run(new Form1());
}
private void btnAdd_Click(object sender, System.EventArgs e)
{
//from www.w3sky.com
//調用MyControlArray的AddNewButton方法
MyControlArray.AddNewButton();
//改變Button 0的BackColor屬性
MyControlArray[0].BackColor = System.Drawing.Color.Red;
}
private void btnRemove_Click(object sender, System.EventArgs e)
{
MyControlArray.Remove();
}
}
}
ButtonArray.cs
using System;
using System.Windows.Forms;
namespace DAddControl
{
/// <summary>
/// ButtonArray 的摘要說明。
/// </summary>
public class ButtonArray
:System.Collections.CollectionBase
{
private readonly System.Windows.Forms.Form HostForm;
public ButtonArray()
{
//
// TODO: 在此處添加建構函式邏輯
//
}
public ButtonArray(System.Windows.Forms.Form host)
{
HostForm = host;
//this.AddNewButton();
}
public System.Windows.Forms.Button AddNewButton()
{
//為Button類建立新的執行個體
System.Windows.Forms.Button aButton = new System.Windows.Forms.Button();
//將該按鈕添加到集合的內部列表
this.List.Add(aButton);
//把控制項集合中的按鈕添加到被HostForm欄位引用的表單
HostForm.Controls.Add(aButton);
//設定該按鈕對象的初始屬性
aButton.Top = Count * 25;
aButton.Left = 100;
aButton.Tag = this.Count;
aButton.Text = "Button " + this.Count.ToString();
aButton.Click += new System.EventHandler(ClickHandler);
return aButton;
}
public System.Windows.Forms.Button this [int Index]
{
get
{
return (System.Windows.Forms.Button) this.List[Index];
}
}
public void Remove()
{
//檢查以確保有按鈕可以刪除
if (this.Count > 0)
{
//from www.w3sky.com
// 從主表單上的控制項集合的數組按鈕數組中刪除最後一個
// 注意在訪問數組時使用了預設屬性
HostForm.Controls.Remove(this[this.Count -1]);
this.List.RemoveAt(this.Count -1);
}
}
public void ClickHandler(Object sender, System.EventArgs e)
{
System.Windows.Forms.MessageBox.Show("You have clicked button " +
((System.Windows.Forms.Button) sender).Tag.ToString());
}
}
}