投稿類別 : 資訊類 篇名 : 陣列控制項技術之研究與應用 作者 : 陳韻如 高雄市立高雄高工 資訊科三年級 陳榮霖 高雄市立高雄高工 資訊科三年級 指導老師 : 莊利吉老師
壹 前言 陣列控制項技術之研究與應用 一 研究動機 控制項陣列 ( 一稱物件陣列 ) 是說讓物件可像陣列一般使用索引值 (index) 來加以控制, 例如要檢查表單上的 9 個 Label 是否都為 7( 物件名稱是 Label1 Label2.Label9), 若不使用控制項陣列則程式寫法如表 1, 冗長不靈活 ; 使用控制項陣列則如表 2, 相同邏輯可輕易轉為其他功能, 例如清除 設定屬性等 雖然 Visual Basic 2008 不再支援控制項陣列, 但是仍可以使用事件模型或其他技巧來自行建立控制項陣列 本研究將探討兩種建立控制項陣列的方式, 並利用這些方法修改初學者常見的水果盤遊 戲程式, 從中體會出控制項陣列的好處 表 1 表 2 Dim Is7 As Boolean = True If Label1.Text = 7 Then If Label2.Text = 7 Then Is7 = False Is7 = False If Is7 = true Then 全部都是 7 至少有一個不是 7 Private LblArray() As Label ' 陣列尚未建立 LblArray = New Label() {Label1, Label2, Label3, } Dim Is7 As Boolean = True For i As Integer = 0 To 8 If LblArray(i).Text <> 7 Then Is7 = False : Exit For If Is7 = true Then 全部都是 7 至少有一個不是 7 二 研究目的 1. 探討 Visual Basic 2008 中控制項陣列的建立方式 2. 藉由比較控制項陣列與非控制項陣列程式之差異, 明白控制項陣列使用時機 三 研究方法 ( 一 ) 研究過程 1
陣列控制項技術之研究與應用 1. 準備期 : 進行文獻探討及建置開發程式所需的環境 2. 演算法設計 : 根據文獻探討結果測試控制項陣列程式設計 3. 程式設計 : 應用控制項陣列技術在水果盤遊戲程式設計中 4. 問題討論 : 與不使用控制項陣列的水果盤遊戲程式進行比較, 探討在程式維護上與擴充上的優缺點 ( 二 ) 研究工具 硬體 : 個人電腦 軟體 :Visual Studio 2008 貳 正文 一 手動加入已有的物件到控制項陣列 1. 執行畫面 : 旋轉幸運 7, 程式功能如圖 1~ 圖 3 3 個 Label 以控制項陣列處理 圖 1 起始畫面圖 2 旋轉中圖 3 停止 ( 沒有 3 個 7, 不顯示錢幣 ) 2. 演算法說明 ( 莊利吉,2008; 阿偉蘇的程式記事本,2008) (1). 將 3 個 Label 3 個 Button 與 1 個 PictureBox 從工具箱拖曳到表單上 (2). 利用下面程式碼將 3 個 Label 變成控制項陣列 Private LblArray() As Label ' 陣列尚未建立 LblArray = New Label() {Label1, Label2, Label3} ' 建立控制項陣列 (3). 使用迴圈方式變換 Label 上的文字 Dim rrnd As New Random LblArray(i).Text = rrnd.(5, 8) (4). 使用迴圈方式檢查 3 個 Label 是否都顯示 7 Dim Is7 As Boolean = True 2
If LblArray(i).Text <> 7 Then Is7 = False : Exit For 陣列控制項技術之研究與應用 3. 原始程式 Private LblArray() As Label ' 陣列尚未建立 Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load Timer1.Enabled = False ' 停止計時 Timer1.Interval = 1000 ' 計時時間為 1 秒 ' 建立控制項陣列 LblArray = New Label() {Label1, Label2, Label3} Private Sub Rotate_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Rotate.Click ' 按下旋轉按鈕時所產生的事件 ' 啟動計時器 Timer1 開始計時 PB1.Visible = False Timer1.Enabled = True Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick 'Timer1 計時時間到時所產生的事件 ' 由於每次時間到時都會重新取 3 個大於等於 5 且小於等於 7 的整數亂數, 所以使用者會感覺數字在跳動 Dim rrnd As New Random LblArray(i).Text = rrnd.(5, 8) Private Sub StopNow_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles StopNow.Click ' 按下停止按鈕所產生的事件 ' 停止計時並檢視目前亂數值以決定是否要顯示圖片 () Dim Is7 As Boolean = True Timer1.Enabled = False If LblArray(i).Text <> 7 Then Is7 = False : Exit For If Is7 Then PB1.Visible = True Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click Me.Close() 二 使用指令建立物件並加入到控制項陣列 1. 執行畫面 : 旋轉幸運 7, 程式功能如圖 4~ 圖 6 3 個 Label 及 3 個 Button 都是以控制 3
項陣列處理 陣列控制項技術之研究與應用 圖 4 起始畫面圖 5 旋轉中圖 6 停止 ( 沒有 3 個 7, 不顯示錢幣 ) 2. 演算法說明 ( 莊利吉,2008;Microsoft,2007; 大內殿堂 @ 余小章,2009) (1). 先將 Label1 Button1 Timer1 與 PictureBox1 從工具箱拖曳到表單上, 如圖 7 注意以下的屬性 Label1.TabIndex = 1 Button1.TabIndex = 4 圖 7 表單設計 (2). 宣告控制項陣列 Private LblArray(2) As Label ' 建立 Label 控制項陣列但尚未指定對應物件 Private BtnArray(2) As Button ' 建立 Button 控制項陣列但尚未指定對應物件 (3). 使用下面指令建立 Label 的控制項陣列 LblArray(0) = Label1 ' 直接加入表單上的 Label For i As Integer = 1 To 2 ' 產生新的 Label 物件 LblArray(i) = New Label ' 新的 Label 的邊框 字型等屬性 LblArray(i).BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D 4
51, 7) 陣列控制項技術之研究與應用 ' 新的 Label 在表單上的位置, 水平並排 LblArray(i).Location = New System.Drawing.Point(LblArray(i - 1).Location.X + ' 新的 Label 的物件名稱, 依序是 Label1, Label2, Label3 LblArray(i).Name = "Label" & i + 1 LblArray(i).TabIndex = 1 + i LblArray(i).Text = "7" ' 將新的 Label 加到表單上 Me.Controls.Add(LblArray(i)) (4). 使用下面指令建立 Button 的控制項陣列 BtnArray(0) = Button1 ' 直接加入表單上的 Button For i As Integer = 1 To 2 ' 產生新的 Button 物件 BtnArray(i) = New Button ' 新的 Button 在表單上的位置, 垂直並排 BtnArray(i).Location = New System.Drawing.Point(BtnArray(0).Location.X, BtnArracation.Y + 24) ' 新的 Button 的物件名稱, 依序是 Button1, Button2, Button3 BtnArray(i).Name = "Button" & i + 1 ' 新的 Button 的長寬 索引 BtnArray(i).Size = New System.Drawing.Size(76, 23) BtnArray(i).TabIndex = 4 + i ' 新的 Button 的顯示文字 If i = 1 Then BtnArray(i).Text = " 停止 " BtnArray(i).Text = " 結束 " BtnArray(i).UseVisualStyleBackColor = True ' 設定新的 Button 的 Click 事件對應到副程式 Button1_Click AddHandler BtnArray(i).Click, AddressOf Button1_Click ' 將新的 Button 加到表單上 Me.Controls.Add(BtnArray(i)) (5). 要將指令產生的物件之相關屬性設成與表單上已有物件相同時, 例如字型大小 邊 框顏色頂等, 可先在專案總管案按下顯示所有檔案, 然後選 Form1.Designer.vb 顯示表單設計指令, 再從中拷貝相關指令到程式編輯視窗修改, 速度較快也較統一, 參 閱圖 8 5
陣列控制項技術之研究與應用 圖 8 3. 原始程式 Private LblArray(2) As Label ' 建立 Label 控制項陣列但尚未指定對應物件 Private BtnArray(2) As Button ' 建立 Button 控制項陣列但尚未指定對應物件 Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load ' 計時器設定 Timer1.Enabled = False ' 停止計時 Timer1.Interval = 1000 ' 計時時間為 1 秒 ' 建立 Label 控制項陣列 LblArray(0) = Label1 ' 直接加入表單上的 Label For i As Integer = 1 To 2 ' 產生新的 Label 物件 LblArray(i) = New Label ' 新的 Label 的邊框 字型 LblArray(i).BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D LblArray(i).Font = New System.Drawing.Font(" 標楷體 ", 20.25!, System.Drawing.FontStyle.Bold, m.drawing.graphicsunit.point, CType(136, Byte)) ' 新的 Label 在表單上的位置, 水平並排 LblArray(i).Location = New System.Drawing.Point(LblArray(i - 1).Location.X + 51, 7) ' 新的 Label 的物件名稱, 依序是 Label1, Label2, Label3 LblArray(i).Name = "Label" & i + 1 ' 新的 Label 的長寬 索引 顯示的文字 文字對齊方式 LblArray(i).Size = New System.Drawing.Size(40, 28) LblArray(i).TabIndex = 1 + i LblArray(i).Text = "7" LblArray(i).TextAlign = System.Drawing.ContentAlignment.MiddleCenter ' 將新的 Label 加到表單上 Me.Controls.Add(LblArray(i)) ' 建立 Button 控制項陣列 BtnArray(0) = Button1 ' 直接加入表單上的 Button For i As Integer = 1 To 2 6
陣列控制項技術之研究與應用 ' 產生新的 Button 物件 BtnArray(i) = New Button ' 新的 Button 在表單上的位置, 垂直並排 BtnArray(i).Location = New System.Drawing.Point(BtnArray(0).Location.X, BtnArray(i - 1).Location.Y ) ' 新的 Button 的物件名稱, 依序是 Button1, Button2, Button3 BtnArray(i).Name = "Button" & i + 1 ' 新的 Button 的長寬 索引 BtnArray(i).Size = New System.Drawing.Size(76, 23) BtnArray(i).TabIndex = 4 + i ' 新的 Button 的顯示文字 If i = 1 Then BtnArray(i).Text = " 停止 " BtnArray(i).Text = " 結束 " BtnArray(i).UseVisualStyleBackColor = True ' 設定新的 Button 的 Click 事件對應到副程式 Button1_Click AddHandler BtnArray(i).Click, AddressOf Button1_Click ' 將新的 Button 加到表單上 Me.Controls.Add(BtnArray(i)) Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click ' 按下 3 個 Button 的任何一個時都會觸發 ' 可以使用 Button 的 Name, TabIndex, Text 等屬性來判斷是哪一個 Button 被按下 If DirectCast(sender, Button).Text = " 旋轉 " Then ' 按下旋轉按鈕時所產生的事件 ' 啟動計時器 Timer1 開始計時 PictureBox1.Visible = False Timer1.Enabled = True If DirectCast(sender, Button).Text = " 停止 " Then ' 按下停止按鈕所產生的事件 ' 停止計時並檢視目前亂數值以決定是否要顯示圖片 Dim Is7 As Boolean = True Timer1.Enabled = False If LblArray(i).Text <> 7 Then Is7 = False : Exit For If Is7 Then PictureBox1.Visible = True If DirectCast(sender, Button).Text = " 結束 " Then Me.Close() Private Sub Timer1_Tick(ByVal sender As Object, ByVal e As System.EventArgs) Handles Timer1.Tick 'Timer1 計時時間到時所產生的事件 ' 由於每次時間到時都會重新取 3 個大於等於 5 且小於等於 7 的整數亂數, 所以使用者會感覺數字在跳動 Dim rrnd As New Random LblArray(i).Text = rrnd.(6, 8) 7
陣列控制項技術之研究與應用 三 研究成果 ( 一 ) 水果盤遊戲功能與執行畫面 1. 程式功能 : 按下旋轉按鈕後, 畫面上方的 3 個水果會不斷更變 之後按下停止按鈕,3 個圖片就會停止變換 若停止時, 若 3 個水果都是草莓, 畫面下方會顯示硬幣圖, 否則不顯 示圖片, 如圖 15 2. 執行畫面 : 如圖 9 ~ 圖 11 3 個 PictureBox 及 3 個 Button 都是以控制項陣列處理 圖 9 水果盤 ( 起始畫面 ) 圖 10 水果盤 ( 旋轉中 ) 圖 11 水果盤 ( 沒有 3 個草苺, 不顯示錢幣 ) ( 二 ) 程式解析 Private PicArray() As PictureBox 'Picture 控制項陣列, 此時尚未建立 Private r(2) As Integer ' 目前 3 個圖片的編號,5 是水梨 6 是西瓜 7 是草莓 Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load Timer1.Enabled = False ' 停止計時 Timer1.Interval = 1000 ' 計時時間為 1 秒 ' 建立控制項陣列 PicArray = New PictureBox() {PB1, PB2, PB3} Private Sub Timer1_Tick(ByVal sender As Object, ByVal e As System.EventArgs) Handles Timer1.Tick 'Timer1 計時時間到時所產生的事件 ' 由於每次時間到時都會重新取 3 個大於等於 5 且小於等於 7 的整數亂數, 所以使用者會感覺數字在跳動 Dim rrnd As New Random r(i) = rrnd.(5, 8) If r(i) = 5 Then PicArray(i).Image = My.Resources. 水梨 If r(i) = 6 Then PicArray(i).Image = My.Resources. 西瓜 PicArray(i).Image = My.Resources. 草莓 Private Sub Rotate_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles 8
陣列控制項技術之研究與應用 Rotate.Click, StopNow.Click, EndApp.Click ' 按下 3 個 Button 的任何一個時都會觸發 ' 可以使用 Button 的 Name, TabIndex, Text 等屬性來判斷是哪一個 Button 被按下 ' 此處檢查物件的名稱 If DirectCast(sender, Button).Name = "Rotate" Then ' 按下旋轉按鈕時所產生的事件 ' 啟動計時器 Timer1 開始計時 PB4.Visible = False Timer1.Enabled = True If DirectCast(sender, Button).Name = "StopNow" Then ' 按下停止按鈕所產生的事件 ' 停止計時並檢視目前亂數值以決定是否要顯示圖片 Timer1.Enabled = False If r(0) = 7 AndAlso r(1) = 7 AndAlso r(2) = 7 Then PB4.Visible = True If DirectCast(sender, Button).Name = "EndApp" Then Me.Close() 參 結論 一 問題與討論 1. 在取亂數以及辨別圖片上, 用非控制項陣列的方式會使程式碼過於冗長, 因此改用控制項陣列可以將程式碼簡化, 在於程式維護上也相對比較簡單 2. 由於使用控制項陣列將程式碼簡化, 擴充上也只需要修改些小地方就能進而做出 9 格或 25 格的水果盤遊戲 相較之下, 非控制項陣列所要做的修改可就不少了, 因為是用 IF 堆疊出來的程式碼, 修改完後, 維護上面也就變得更加困難 二 未來研究建議 1. 將水果盤擴充成 9 格或更多格數, 再比較其中控制項陣列的差異 2. 嘗試將控制項陣列套用至管理系統類型的程式, 探討其優缺點 肆 引註資料 1. 莊利吉 (2008) 物件導向程式設計:Windows 程式設計 (VB 2008) 擷取日期 2011 年 9 月 25 日, 擷取自莊利吉教學網站 :http://lichi.ksvs.kh.edu.tw 2. 章立民 (2006) Visual Basic 2005 程式開發與介面設計秘訣 高雄市 : 碁峰 3.Microsoft. (2007 年 11 月 ). Visual Basic 6.0 使用者可用的控制項陣列. 擷取自 MSDN: http://msdn.microsoft.com/zh-tw/library/kxt4418a%28v=vs.90%29.aspx 4. 大內殿堂 @ 余小章. (2009 年 6 月 1 日 ). 如何設定控制項陣列 / 動態加入控制項. 擷取自余小章 @ 大內殿堂 : http://www.dotblogs.com.tw/yc421206/archive/2009/06/01/8636.aspx 5. 阿偉蘇的程式記事本. (2008 年 3 月 29 日 ). 控制項陣列化. 擷取自阿偉蘇的程式記事本 : http://www.wretch.cc/blog/awaysu/23104346# 9