第
This presentation is the property of its rightful owner.
Sponsored Links
1 / 193

第 8 章 PowerPoint PPT Presentation


  • 57 Views
  • Uploaded on
  • Presentation posted in: General

第 8 章. 陣列. 本章重點提要. 8-1 陣列的基本觀念與用法 8-2 陣列進階 8-3 ListBox ( 清單方塊 ) 控制項 8-4 ComboBox ( 下拉式清單方塊 ) 控制項. 本章閱讀建議. 本章閱讀建議新觀念 Microsoft Visual Basic 程式設計陣列是一種儲存資料的結構 , 經常用於多筆資料的處理工作中 , 可以說是變數的功能延伸 , 是提升程式效率一定要會的基礎。底下是本章各節的閱讀建議:. 本章閱讀建議.

Download Presentation

第 8 章

An Image/Link below is provided (as is) to download presentation

Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.


- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -

Presentation Transcript


8 4516628

第 8 章

陣列


8 4516628

本章重點提要

  • 8-1陣列的基本觀念與用法

  • 8-2 陣列進階

  • 8-3 ListBox (清單方塊) 控制項

  • 8-4 ComboBox (下拉式清單方塊) 控制項


8 4516628

本章閱讀建議

  • 本章閱讀建議新觀念 Microsoft Visual Basic 程式設計陣列是一種儲存資料的結構, 經常用於多筆資料的處理工作中, 可以說是變數的功能延伸, 是提升程式效率一定要會的基礎。底下是本章各節的閱讀建議:


8 4516628

本章閱讀建議

  • 8-1 陣列的基本觀念與用法:陣列對初學者來說可能比較陌生, 學習的重點在於如何宣告陣列、以及如何存取陣列中的資料。讀者只要跟著上機實例操作, 很快就能熟悉陣列的基本用法。

  • 8-2 陣列進階:陣列的進階用法包含:排序、搜尋、二維陣列...等, 在進階程式設計中, 這些主題經常會被用到。本節的上機實例比較難一點, 但多花點時間學習卻是值得的。


8 4516628

本章閱讀建議

  • 8-3 ListBox (清單方塊) 控制項:ListBox 是一種『可以顯示多項資料供使用者選取』的控制項, 具備了單選、複選、排序、搜尋...等功能, 閱讀時建議透過上機實例來瞭解這些功能。

  • 8-4 ComboBox (下拉式清單方塊) 控制項:ComboBox 就是將TextBox 及 ListBox 組合起來的控制項, 讓使用者可以用打字或選取的方式來輸入資料。學會 ListBox 後再來學 ComboBox,應該會覺得很輕鬆才對。


8 4516628

8-1 陣列的基本觀念與用法

  • 陣列 (Array) 與變數一樣, 都是用來儲存資料, 所不同的是每一個變數只能儲存一項資料, 而每一個陣列則可儲存多項的資料。


8 4516628

陣列的宣告與使用

  • 陣列必須先宣告才能使用, 宣告的格式和變數很像, 例如:

  • 最簡單的陣列宣告格式是:


8 4516628

陣列的宣告與使用

  • 其中 N 代表最後一項資料的編號, 例如:


8 4516628

陣列的宣告與使用

  • 一旦宣告了陣列, 我們就可以使用『陣列名稱(編號)』的方式, 來存取陣列中指定編號的資料項, 例如:


8 4516628

陣列的宣告與使用

  • 在術語上, 陣列中的每一個資料項叫做一個『元素』(Element), 用來指定某一個元素的 0、1、2、... 編號, 則叫做『索引』(Index)或『註標』(Subscript), 如下圖所示:

  • 請注意, Dim X(4) 所宣告的陣列是包含 5 個元素 (索引 0~4), 而非 4個元素喔!


8 4516628

指定陣列的資料型別

  • 在宣告陣列時也可以用 As 來指定資料型別, 其寫法就和宣告變數一樣, 例如:


8 4516628

指定陣列的資料型別

  • 在宣告陣列時指定資料型別, 會有什麼好處?(可複選)

    (1) 在存取陣列中的元素時, 會比較有彈性。

    (2) 可以提升執行效率。

    (3) 程式比較不容易出錯。

    (4) 讓程式變得比較複雜, 以避免被別人看懂。


8 4516628

指定陣列的資料型別

(2)、(3)

不宣告型別時, 在使用上會比較有彈性, 因為可以將任意型別的資料存入陣列元素中。若將陣列宣告為特定型別, 則只能存入該型別的資料, 因此彈性較低;但也由於型別固定, 所以執行效率會比較好, 同時也可避免存入錯誤型別的資料, 例如將字串資料存入成績陣列中, 那麼在比較成績時 "100" 會小於 "99" (因為字串是由第 1個字元開始比較)!


8 4516628

陣列的型別 vs 陣列中元素的型別

  • 當我們宣告了陣列的型別時, 例如:

  • 那麼 X 陣列中的每個元素 (X(0)、X(1)) 都是 String 型別, 而 X 陣列本身則為『String()』型別。換句話說, 在型別名稱後面加上 (), 就表示其為陣列的型別,例如 Byte()、Integer() 等。


8 4516628

陣列的型別 vs 陣列中元素的型別

  • 另外, 陣列的大小與陣列型別無關, 例如:


8 4516628

使用陣列的注意事項

  • 使用陣列時應注意以下幾件事:

    • 不能夠一次讀取或指定整個陣列的資料, 例如:


8 4516628

使用陣列的注意事項

  • 存取陣列中的元素時, 所指定的索引不能超出陣列的索引範圍,例如:


8 4516628

陣列的優點

  • 陣列的優點, 就是可以把多個資料項排列起來, 然後用數值的編號(索引) 來存取。例如, 我們將 5 項資料放到 5 個變數裡面, 那麼要輸出時就必須一一指定變數名稱:


8 4516628

陣列的優點

  • 如果我們把這 5 項資料放在陣列裡面, 那麼只需要一個 For 迴圈就可以把它們全部輸出了, 例如:


8 4516628

陣列的優點

  • 而即使資料的項數多達 100 項, 也只要將上述程式 For 敘述中的 4 改成 99, 就可輸出全部的資料;但若換成輸出 100 個變數可就累了。

  • 寫一主控台程式可輸入 5 份數值資料, 然後顛倒順序輸出這 5 份資料。

  • 建立主控台應用程式專案 Ch08-01。

  • 在程式模組中輸入以下程式:


8 4516628

陣列的優點


8 4516628

陣列的優點

  • 執行程式, 假設依序輸入 10, 20, 30, 40, 50 五份資料, 則程式執行結果如下:

    在以上程式中, 我們使用 Val() 函式將輸入的資料轉換為數值。請注意第二個 For 迴圈要加上『Step -1』, 否則程式不會進入該迴圈執行!


8 4516628

陣列的優點

  • 寫一程式輸入 5 個數值資料, 輸入完畢後, 輸出這 5 個數值的最大值及最小值。

  • 建立主控台應用程式專案 Ch08-02。

  • 在程式模組中輸入以下程式:


8 4516628

陣列的優點


8 4516628

陣列的優點

  • 執行程式, 假設依序輸入 10, 100, -99, 345, 50 五份整數,則程式執行結果如下:


8 4516628

陣列的優點

一開始還不知道最小值 (Min) 及最大值 (Max), 所以先將陣列第 0個元素視為最小值及最大值;接著, 就用迴圈來與第 1~4 個元素比較, 如果有更小的值則將之設為最小值, 如果有更大的值則將之設為最大值。當所有的元素都比完之後, 就可將最小值 (Min) 及最大值 (Max) 顯示出來了。


8 4516628

陣列的優點

  • 想想看, 如果修改第 2 及 6 行的程式:

    然後重新執行程式, 並輸入同樣的資料, 猜猜看結果如何?結果最小值為 -99, 但最大值卻是 50 (而不是 345), 這是為什麼呢?


8 4516628

陣列的優點

Console.ReadLine() 會讀入『字串』資料, 由於在宣告陣列及變數時沒有指定型別, 因此輸入的字串會直接存入陣列中並拿來做比較, 而在比較字串時 "50" 會大於 "345", 所以最大值會變成 "50", 而不是 "345"。


8 4516628

陣列的初值設定

  • 就像變數可以在宣告時指定初值一樣, 陣列也不例外, 請看以下實例:

  • 設定的方式是將所有資料以逗號分隔, 然後寫在 { } 裡面。不過請注意, 指定初值時, 不能再指定最大索引值:


8 4516628

陣列的初值設定

  • 當指定初值時, VB 會自動計算元素個數, 以上面的 X 陣列來說, 其元素有 3 個, 因此索引範圍是 0~2。另外, 陣列的型別並不受初值的影響, 這一點和變數不同, 例如底下我們用 Typename() 函式來查看型別:


8 4516628

陣列的初值設定

  • 陣列的型別名稱後面必須加小括號, 例如『String()』就是指『字串陣列』型別。在 String() 型別的陣列中, 每個元素均為 String 型別。


8 4516628

陣列的初值設定

  • 顯示春、夏、秋、冬四季的中英文對照表。

  • 建立 Windows 應用程式專案 Ch08-03。


8 4516628

陣列的初值設定

  • 在表單中加入一 Label 控制項並將其 Font/Size 屬性設為 20:


8 4516628

陣列的初值設定

  • 在表單空白處雙按滑鼠, 建立表單的 Load 事件程序:


8 4516628

陣列的初值設定

  • 按[F5] 鍵執行程式, 即可顯示四季的中英文對照表。


8 4516628

陣列的初值設定

  • 因為中文季節及英文季節的陣列索引範圍是 0~3。那為什麼要將3 改成 Ubound(中文季節) 呢?因為 UBound() 會自動算出陣列後一個元素的索引值!

  • 以中文季節為例, 最後一個元素的索引是3, 所以 Ubound(中文季節) 就等於 3;使用 UBound 的優點是不用自己計算陣列示素的個數, 以避免不必要的錯誤。


8 4516628

陣列的初值設定

  • 某公司有 5 個員工, 請建立一登入程式, 員工必須輸入正確的『帳號』及『密碼』才能登入。


8 4516628

陣列的初值設定

  • 建立 Windows Form 應用程式專案 Ch08-04。

  • 在表單中加入控制項並設定如下:


8 4516628

陣列的初值設定


8 4516628

陣列的初值設定

  • 雙按 Button1 按鈕, 撰寫程式如下:


8 4516628

陣列的初值設定


8 4516628

陣列的初值設定

  • 按[F5]鍵實地測試看看。


8 4516628

陣列的初值設定


8 4516628

陣列的初值設定

  • 建立一主控台程式, 可讓使用者輸入 1~7 的數值, 然後顯示該數值對應到星期幾, 如下圖所示。若輸入 1~7 以外的資料, 則結束程式。


8 4516628

陣列的初值設定


For each for

For Each:不需要計數器的 For 迴圈

  • For Each 是 For 迴圈的變形, 可以由陣列中一一取出每一個元素來處理, 寫法如下:

  • 例如底下是將陣列中所有元素加總起來的程式:


For each for1

For Each:不需要計數器的 For 迴圈

  • 變數 n 也可以在 For Each 之前事先宣告好, 若沒事先宣告則在 For Each 中會自動宣告, 並且可以用 As 來指定型別。

  • 寫一程式讓使用者輸入一串以逗號分隔的成績資料, 然後顯示所有成績的筆數、總分、及平均, 如下圖所示。


For each for2

For Each:不需要計數器的 For 迴圈

  • 開啟範例專案 Ch08-05, 我們已準備好所需的表單及控制項:


For each for3

For Each:不需要計數器的 For 迴圈

  • 請雙按 Button1, 建立 Button1.Click 事件程序:


For each for4

For Each:不需要計數器的 For 迴圈


8 4516628

8-2 陣列進階

動態改變陣列的大小

  • 當我們用 Dim 宣告一個陣列之後, 其大小就確定下來了, 例如:

  • 但有時候我們希望在程式的執行過程中, 能動態改變陣列的大小,這時候就必須用到 ReDim敘述。


8 4516628

動態改變陣列的大小

  • 假設原有一陣列 A, 而我們想將其大小改變成 11, 則敘述如下:


8 4516628

動態改變陣列的大小

  • 以上的 Preserve 就是『保留』的意思, 請看以下二段不同的程式:


8 4516628

動態改變陣列的大小

  • 以上二段程式都是將原本只有 3 個元素的陣列放大成為含有 6 個元素的陣列, 但程式一在執行 ReDim 之後, 原本 A(0)、A(1)、A(2)所含有的 "Word"、"Excel"、"PowerPoint" 資料都會消失。

  • 而程式二因為在執行 ReDim 時有加 Preserve, 所以會保留 A(0)、A(1)、A(2) 原有的資料。


8 4516628

動態改變陣列的大小

  • 寫一程式讀取使用者輸入的資料, 並一一存入陣列中, 直到使用者輸入空字串為止, 最後並顯示所輸入資料的筆數。

  • 建立主控台應用程式專案 Ch08-06。

  • 輸入以下程式:


8 4516628

動態改變陣列的大小


8 4516628

動態改變陣列的大小

  • 執行程式, 假設輸入 John、Peter、Tom、Mary, 然後按[Enter]鍵結束輸入:


8 4516628

動態改變陣列的大小

由於不知道使用者會輸入幾筆資料, 所以使用『Dim 陣列() AsString』宣告一個空陣列, 並用無條件限制的 Do-Loop 迴圈不斷要求使用者輸入資料, 當使用者輸入空字串時即用 Exit Do 跳離迴圈,否則就用 ReDim Preserve 來加大陣列, 並將輸入的資料存入最後一個元素中。


8 4516628

動態改變陣列的大小

  • 筆數的預設值為 0, 因此第一次執行『ReDim Preserve 陣列(筆數) 』時, 可讓陣列中含有 1 筆資料 (就是陣列(0)元素);到了第二次執行迴圈時筆數等於 1, 因此『ReDim Preserve 陣列(1) 』可使陣列含有 2 筆資料, 接下來的迴圈則以此類推...。此外, 請注意ReDim 後面要加 Preserve 保留字。


8 4516628

陣列與排序

  • 所謂『排序』 (Sort) 就是將一連串資料從小排到大 (或反之), 例如{ 3, 9, 15, 8, 4 } 排序後就成為 { 3, 4, 8, 9, 15 }。想要撰寫排序陣列的程式, 對初學者來說並不簡單, 不過 VB 已經提供了現成的方法 Array.Sort( ), 我們只要直接使用就好, 例如:


8 4516628

陣列與排序

  • 寫一程式讓使用者輸入 5 個數值, 然後將這些數值由小排到大顯示出來。

  • 建立主控台應用程式專案 Ch08-07。

  • 輸入以下程式:


8 4516628

陣列與排序

  • 執行程式, 輸入 22、33、-99、100、5, 則執行結果如圖:


8 4516628

陣列與排序

在以上程式中, 我們將陣列 X 宣告為 Integer() 型別, 因此執行Array.Sort( ) 時會以整數的方式來排序;若將 X 宣告為 String() 型別, 則 Array.Sort( ) 會以字串方式排序, 則 22、33、-99、100、5排序後會變成 100、22、33、5、-99。


8 4516628

陣列與排序

  • 如果以上程式還要顯示最大值及最小值, 該增加什麼敘述呢?

  • 如果以上程式要改為『從大排到小』顯示出來, 該如何修改呢?


8 4516628

陣列與排序

將以下程式段落:


8 4516628

陣列與排序

  • 以上程式只是改變顯示的順序, 但陣列元素的順序還是沒變。如果要改變陣列元素的順序, 使其『從大排到小』, 則可在執行 Array.Sort(X) 之後, 再執行 Array.Reverse(X)將元素的順序顛倒過來,例如 X 在排序後的順序為 -99、5、22、33、100, 那麼 Reverse後會變成 100、33、22、5、-99。


8 4516628

陣列與排序

  • 有以下兩個陣列, 第一個陣列儲存學生的姓名, 第二個陣列儲存學生的數學成績:

    請將這兩個陣列顯示成:


8 4516628

陣列與排序

  • 建立主控台應用程式專案 Ch08-08。

  • 輸入以下程式:


8 4516628

陣列與排序

  • 執行程式, 即可按照大小順序列出資料。


8 4516628

陣列與搜尋

  • 有時候我們需要搜尋陣列中是否含有某一種資料, 例如有一『姓名』陣列如下:

  • 要如何找出 "Peter" 在『姓名』陣列中的位置 (索引) 呢?如果您已熟悉陣列的特性, 並且懂得善用 For 迴圈, 大概會寫出以下程式:


8 4516628

陣列與搜尋


8 4516628

陣列與搜尋

  • 在以上程式中, 值得注意的是, 離開 For 迴圈後, 我們可以判斷 i 的值是否大於 UBound(姓名), 以決定是否已經搜尋到資料。

  • 不過, 呼叫 Array.IndexOf() 才是更高明的方法!同樣是搜尋"Peter", 改用 Array.IndexOf() 的程式如下:


8 4516628

陣列與搜尋

  • 有關 Array.IndexOf( ) 的用法如下:

  • 其中傳回值表示搜尋的結果, 當傳回值 < 0 時, 表示沒有找到;當傳回值 >= 0 時, 表示已找到, 而且傳回值等於欲搜尋資料的位置(索引)。以上面的例子來說, "Peter" 位於『姓名』陣列的位置 (索引) 等於 2, 所以傳回值等於 2。


8 4516628

陣列與搜尋

  • 有四個陣列如下, 分別記錄學生的姓名, 及數學、國文、英文的成績。試寫一程式可輸入學生姓名來查詢各科成績。


8 4516628

陣列與搜尋

  • 請開啟範例專案 Ch08-09, 我們已經準備好所需的表單:


8 4516628

陣列與搜尋

  • 切換到程式碼視窗, 我們已在 Button1.Click 事件程序中宣告了所需陣列, 請繼續加入查詢成績的程式:


8 4516628

陣列與搜尋

  • 執行程式, 分別查詢『方正一、葉小毛、周杰倫』, 結果應如下:


8 4516628

搜尋多筆資料

  • 有時候陣列中會有一些相同的資料, 例如存放全班數學成績的陣列中, 就難免會有分數相同的情況出現。假如我們想找出所有 100分的同學, 該怎麼找呢?

  • 找出數學成績 100 分的同學。


8 4516628

搜尋多筆資料

  • 開啟範例專案 Ch08-10, 我們已在 Main() 程序中加入所需陣列, 請繼續完成尋找 100 分的程式:


8 4516628

搜尋多筆資料

  • 執行程式, 結果如下:


8 4516628

搜尋多筆資料

以上程式出現了二個 Array.IndexOf( ) , 而第二個 Array.IndexOf( )比第一個多了一個參數:

第一個 Array.IndexOf( ) 會從第 0 筆資料開始搜尋 (相當於IndexOf(數學, 100, 0)), 而第二個 Array.IndexOf( ) 會從第『索引+1』筆資料開始搜尋。


8 4516628

搜尋多筆資料

以本例來說, 100 出現在第 3、6、8 的位置, 所以第一個 Array.IndexOf( ) 會搜尋到第 3 筆資料;接下來第二個 Array.IndexOf( )會從第 4 (=3+1) 筆開始搜尋, 然後找到第 6 筆資料;接著繼續執行 While 迴圈, 然後從第 7 (=6+1) 筆資料開始搜尋, 又找到第 8 筆資料。


8 4516628

二維陣列

  • 除了一一排列的資料之外, 我們也可能需要處理表格式的資料, 例如:


8 4516628

二維陣列

  • 以這個表格為例, 計有 5 列、4 行, 所以共有 5 X 4 項資料, 如果想用陣列來儲存這個表格, 可以這樣宣告:


8 4516628

二維陣列

  • 像這樣含有二個索引的陣列, 稱為『二維陣列』, 而之前只有一個索引的則稱為『一維陣列』。要存取二維陣列中的元素時, 也必須使用到 2 個索引, 例如:


8 4516628

二維陣列

  • 如果我們將整個陣列的『索引』都標示出來, 則是:


8 4516628

二維陣列

  • 將下面程式中『姓名、數學、國文、英文』等四個陣列的資料, 合併寫入一個二維陣列中。

  • 開啟範例專案 Ch08-11, 我們已宣告好所需的一維陣列,請繼續完成轉入二維陣列的程式:


8 4516628

二維陣列


8 4516628

二維陣列

  • 執行程式, 結果如下:


8 4516628

二維陣列


8 4516628

二維陣列


8 4516628

取得陣列最大索引與元素個數的方法

  • UBound() 函式的第 2 個參數預設為 1 (第 1 維), 因此 UBound(成績, 1) 也可簡寫為 UBound(成績)。除了 UBound() 之外, 也可改用陣列本身的方法及屬性, 來取得其最大索引或元素個數:


8 4516628

二維陣列

  • 在前面程式的最後, 如果執行 UBound(成績, 2), 結果會是多少?

    3 (就是第 2 維度:『行』的最大索引值)。


8 4516628

二維陣列的初值設定

  • 就像一維陣列可以設定初值, 二維陣列也同樣可以, 例如:

  • 結果 Y 陣列將成為一個 3 X 2 的陣列, 內容如下:


8 4516628

二維陣列的初值設定

  • 接著讓我們來看看剛才的上機範例 (Ch08-11) 中, 成績陣列應如何指定初值:


8 4516628

二維陣列的初值設定

  • 根據以上陣列, 計算出每位同學的總成績, 並依據總成績的高低輸出名次、編號、姓名、及總成績, 如下圖所示:


8 4516628

二維陣列的初值設定

  • 開啟範例專案 Ch08-12, 我們已宣告好所需的二維陣列,請繼續完成總成績的計算及排名:


8 4516628

二維陣列的初值設定


8 4516628

二維陣列的初值設定

  • 執行程式, 觀看結果是否正確。

    以上程式利用總分陣列來儲存每個同學的總成績, 並用編號陣列來儲存對應的索引值, 儲存後的結果如下:


8 4516628

二維陣列的初值設定


8 4516628

二維陣列的初值設定

接著會針對總分陣列排序 (編號陣列也同步更改順序), 然後再顛倒順序為由大排到小, 結果如下:


8 4516628

二維陣列的初值設定

  • 您可發現總分的排列順序已經和成績的順序不同, 但透過編號所記錄的『索引位置』, 總分及成績依然保持著正確的對應關係。舉例來說, 總分第一筆資料 298 所對應的編號為 6, 而 6 又對應到成績陣列的 { “方正一”,100,98,100 }。

  • 接下來程式就利用這種對應關係, 依總分的順序將資料全部輸出,並順便加上名次資料 (由 1 開始循序遞增)。值得注意的是, 在迴圈中我們用『成績(編號(i), 0)』來讀取姓名資料, 假設目前要輸出第0 列的資料, 則『編號(0)』為 6, 而『成績(6, 0)』則為 "方正一"。


8 4516628

二維陣列的初值設定

  • 寫一程式可輸入『綜合所得淨額』, 然後依下表計算『應納稅額』, 並將公式及結果都顯示出來。計算公式為:

    『綜合所得淨額 * 稅率 - 累進差額 = 應納稅額』。


8 4516628

二維陣列的初值設定

撰寫 Button1.Click 事件程序如下:(您可開啟範例專案 Ch08-13來修改)


8 4516628

二維陣列的初值設定


8 3 listbox

8-3 ListBox (清單方塊) 控制項

  • 變數只能存放單項資料, 而陣列則可以存放多項資料, ListBox (清單方塊) 跟陣列一樣可以存放多項資料, 相對於只能存放單項資料的控制項 (包含 Label、TextBox、RadioButton、CheckBox 等) 有其方便之處。


Listbox

ListBox (清單方塊) 控制項

  • ListBox 的功用在列出所有相關的資料供使用者選取, 在 Windows應用程式中, 其應用相當普遍, 例如字型設定交談窗, 就會利用ListBox 列出所有字型供使用者選取:


Listbox1

使用 ListBox 的基礎

  • 當 被佈置在表單時, 其顯示區中會出現 "ListBox1" 的文字, 但這不是 ListBox 裡的資料, 而是 ListBox 的名稱 (在程式執行之後, 此一名稱就會消失), 想要讓 ListBox 發揮應有的功用, 必須先加入資料到 ListBox 中。


Listbox2

使用 ListBox 的基礎

  • 在表單上佈置一 ListBox, 並且加入 Peter、Jimmy、Thomas、Nick 等4 項資料。

  • 建立 Windows Form 應用程式專案 Ch08-14。

  • 在表單上佈置一 ListBox, 接著選取屬性窗格中的 Items屬性, 然後按下 Items 屬性的

    鈕, 過程如下:


Listbox3

使用 ListBox 的基礎


Listbox4

使用 ListBox 的基礎

  • 接著會出現『字串集合編輯器』視窗, 請在其中輸入Peter、Jimmy、Thomas、Nick 等 4 行資料, 然後按確定鈕,過程如下:


Listbox5

使用 ListBox 的基礎

  • 這樣就完成資料的輸入了。以後若要修改 ListBox 中的資料, 只要選取屬性窗格中的 Items 屬性, 然後按下 Items 屬性的 鈕, 接著在『字串集合編輯器』視窗中進行修改即可, 過程與輸入資料相同。


Listbox6

善用 ListBox 的『智慧標籤』功能

  • 要設定 ListBox 的 Items 屬性, 還有一種更方便的方法, 就是使用『智慧標籤』功能。當 ListBox 被選取時, 在選取框的右上方會出現一個向右的小三角型:


Listbox7

ListBox 的被選項

  • 被加入於 ListBox 的資料將來都會成為程式的選項, 而我們在程式中讀取被選取選項的方法是 ListBox.SelectedItem 及 ListBox.SelectedIndex。假設 ListBox1 之中含有 Peter、Jimmy、Thomas、Nick 等 4 個選項, 而使用者選取了 Thomas 這個選項,則:


Listbox8

ListBox 的被選項

  • 但如果沒有任何一項被選取, 則 ListBox1.SelectedItem 等於 "" (空字串), 而 ListBox1.SelectedIndex 等於 -1。

  • 另一方面, 我們也可以設定 ListBox.SelectedItem 或 ListBox.SelectedIndex 藉以改變 ListBox 的被選項, 例如:


Listbox9

ListBox 的被選項

  • 利用 ListBox 設計『字型設定程式』。


Listbox10

ListBox 的被選項

  • 建立 Windows Form 應用程式專案 Ch08-15。

  • 在表單上佈置一個 Label、三個 ListBox、及一個 Button,如下圖:


Listbox11

ListBox 的被選項

  • 其中所設定的屬性如下:


Listbox12

ListBox 的被選項

  • 在 Button1.Click 事件程序中輸入以下程式:


Listbox13

ListBox 的被選項


Listbox14

ListBox 的被選項

  • 執行程式, 分別選取不同的字型名稱、樣式、及大小來測試效果。


Listbox15

ListBox 的被選項

  • 在上面最後一行不可將 “12”寫成 12, 因為儲存在 ListBox3 的Items 屬性中的是字串 “12”, 而 “12”並不等於 12, 所以若將SelectedItem 設為 12, 將不會有任何選取的效果。

  • 有關字型設定的說明, 已在第 6-5 節最後一單元展示各種字型效果中介紹過, 還不熟悉的讀者可回頭複習一下。


Listbox16

ListBox 與資料複選

  • 讓使用者『複選』ListBox 的資料, 也是應用程式常見的需求。如果我們想提供一個可複選的 ListBox, 首先要將其 SelectionMode屬性設成 MultiSimple或 MultiExtended。


8 4516628

複選資料的方式

  • 雖然將 SelectionMode 屬性設成 MultiSimple 或 MultiExtended,都可使 ListBox 得以被複選, 但將來使用者選取的方式卻有一點差異:

    • MultiSimple:當使用者以滑鼠點選資料時, 若該資料尚未被選取, 則點選表示選取;若該資料已經被選取, 則點選變成取消選取。例如:


8 4516628

複選資料的方式


8 4516628

複選資料的方式

  • MultiExtended:除了可以用滑鼠點選資料外, 還可用拉曳法來選取連續的多筆資料, 但每次拉曳或點選資料時, 先前所有已選取的資料都會被取消 (等同於每次都重新選取):


8 4516628

複選資料的方式

  • 如果點選時要保留原有被選取的資料, 則要先按著[Ctrl] 鍵再選取;若按著[Ctrl] 鍵點選已選取的資料, 則可取消該資料的選取,但不影響其他資料的選取狀態。

  • 另外還有一種『區塊』的選取方式, 方法是先點選第一筆資料,接著按住[Shift] 鍵, 再點選另一筆資料, 則兩筆資料之間的資料都會被選取, 例如:


8 4516628

讀取複選的資料

  • 將來程式執行時要如何判斷哪些資料被選取了呢?方法是讀取SelectedItems 屬性 (注意最後有 s), 其相關敘述如下:

  • 以下讓我們以實例來瞭解用法。


8 4516628

讀取複選的資料

  • 從霹靂小組中, 挑選出搶救人質的隊員。


8 4516628

讀取複選的資料

  • 開啟範例專案 Ch08-16, 視窗已佈置如下:


8 4516628

讀取複選的資料

  • 其中 ListBox1 設定了以下屬性:

  • 在 Button1.Click 事件程序中輸入以下程式:


8 4516628

讀取複選的資料

  • 執行程式, 選取多個項目測試看看。

    以上程式的重點在於 For 迴圈, 假設我們選取了 Peter, Thomas,Karen 等 3 項資料, 則 ListBox1.SelectedItems.Count 等於 3, 而For 迴圈成為『For i = 0 To 2』, 被選項則分別等於:


Listbox17

以程式動態增刪修改 ListBox 的資料

  • 除了讀取使用者所選取的資料外, 我們也可以動態地增加或刪除ListBox 中的資料, 其敘述如下:


Listbox18

以程式動態增刪修改 ListBox 的資料

  • 假設 ListBox1 原有的資料包含 Peter、Jimmy、Thomas、Nick, 讓我們來看看執行以下敘述後, ListBox1 會有什麼變化:


Listbox19

以程式動態增刪修改 ListBox 的資料


Listbox20

以程式動態增刪修改 ListBox 的資料


Listbox21

以程式動態增刪修改 ListBox 的資料

  • 至於修改資料的內容所使用的敘述則是:


Listbox22

以程式動態增刪修改 ListBox 的資料

  • 利用 TextBox 及 ListBox 寫一個可以讓使用者輸入、修改、刪除資料的程式。

  • 建立 Windows Form 應用程式專案 Ch08-17。

  • 在表單上佈置 4 個控制項如下:


Listbox23

以程式動態增刪修改 ListBox 的資料

  • 在[輸入/修改]Button1.Click 事件程序中輸入以下程式:

  • 請注意, 當 ListBox.SelectedIndex 為 -1 時, 就表示沒有選取任何資料。反之, 如果有被選項, 則 ListBox.SelectedIndex 的值會等於被選項的索引值 ( 由 0 起算), 因此其值必定 >= 0。


Listbox24

以程式動態增刪修改 ListBox 的資料

  • 撰寫[刪除] Button2.Click 事件程序:

  • 執行程式, 然後參考以下步驟進行測試:


Listbox25

以程式動態增刪修改 ListBox 的資料

當 ListBox 為『單選』狀態 (SelectionMode 屬性 = One) 時, 使用者一旦選取了任一項資料, 就無法再回到未選取的狀態。而以上程式要『新增』資料時, 卻必須是在 ListBox 未選取資料的狀態才能新增。


Listbox26

以程式動態增刪修改 ListBox 的資料

要解決此問題有許多種方法, 例如將『輸入/修改』鈕分成『輸入』、『修改』二個按鈕, 分別掌管新增與修改的工作。底下我們使用比較簡單的做法, 就是在 TextBox1 取得輸入焦點時, 即讓ListBox1 變成未選取資料的狀態, 此方法只須新增一個 TextBox1.GotFocus (取得輸入焦點) 事件程序:


8 4516628

連續刪除多筆資料

  • 在增刪修改 ListBox 資料的過程中, 以連續刪除多筆資料最容易出錯。以下讓筆者舉例說明, 假設有一 ListBox1, 其中包含 Peter、Jimmy、Thomas、Nick、Jeffrey 等 5 筆資料, 如果我們想刪除第0、1、2 筆資料 (也就是 Peter、Jimmy、Thomas), 初步撰寫程式如下:


8 4516628

連續刪除多筆資料

  • 但實際執行之後, 並不是 Peter、Jimmy、Thomas 被刪除, 而是Peter、Thomas、Jeffrey 被刪除, 為什麼呢?且看以下圖解:


8 4516628

連續刪除多筆資料

  • 每當資料被刪除時, 後面的資料就會往前遞補, 而導致順序改變(索引值會減 1), 因此接下來刪除的資料就不對了。要避免這個問題, 只要改為『由後面往前刪除』即可:


8 4516628

連續刪除多筆資料

  • 由於刪除後面的資料並不會影響到前面資料的順序, 所以能順利地刪除所有想刪除的資料。一般來說, 通常是『複選』的 ListBox 才需要連續刪除多筆資料, 例如:


8 4516628

連續刪除多筆資料

  • 此時就必須借助 ListBox.SelectedIndices 屬性了!此屬性會儲存所有被選取資料的索引, 我們以上圖為例來示範:

  • 此時若要將選取的資料刪除, 則可用『由大到小』的順序來一一刪除:


8 4516628

連續刪除多筆資料

  • 兩個 ListBox 之間的資料互換。

  • 建立 Windows Form 應用程式專案 Ch08-18。

  • 在表單中佈置二個 ListBox 及二個 Button, 如下圖:


8 4516628

連續刪除多筆資料

  • 其中 ListBox 所設定的屬性如下:

  • 建立 Button1 [>>]的 Click 事件程序:


8 4516628

連續刪除多筆資料

  • 接著建立 Button2[<<] 的 Click 事件程序。程序邏輯與Button1 相同, 只不過操作的對象顛倒過來:


8 4516628

連續刪除多筆資料

  • 執行程式, 試著選取左邊 ListBox 的選項, 然後按[>>] 將其移到右邊的 ListBox, 接著再試著選取右邊 ListBox 的選項, 然後按下 [<<] 鈕將其移到左的 ListBox。


8 4516628

資料的搜尋

  • 搜尋 ListBox 的資料, 比較笨的方法是寫一個 For 迴圈逐一比較每一個選項, 例如:


8 4516628

資料的搜尋

  • 其中 ListBox1.Items.Count 表示 ListBox1 之中的選項數目, 而 For迴圈則是用來逐一比較每一個選項。此一方法雖然可以用來搜尋資料, 但更聰明的方法是使用 IndexOf( ) 方法, 其敘述如下:


8 4516628

資料的搜尋

  • 如果 ListBox 含有所要搜尋的資料, 則傳回值 i 等於資料的位置,否則等於 -1。舉例來看, 假設 ListBox1 含有 Peter、Jimmy、Thomas、Nick 等 4 項資料, 則:


8 4516628

資料的搜尋

  • 寫一程式, 可將輸入的資料加到 ListBox 中, 但已存在於 ListBox 中的資料則不再加入。

  • 建立 Windows Form 應用程式專案 Ch08-19。

  • 在表單中佈置如下:


8 4516628

資料的搜尋

  • 在 Button1.Click 事件程序中輸入以下程式:


8 4516628

資料的搜尋

  • 中, 但輸入第 5 項資料Peter 時, 會顯示請將 Form1 的 AcceptButton ( 預設按鈕) 屬性設為Button1, 這樣使用者在打好文字後按[Enter] 鍵便可輸入, 而不必再抓滑鼠去按[輸入] 鈕。

  • 執行程式, 然後依序輸入 Peter、Jimmy、Thomas、Nick、Peter, 結果前 4 項資料都可以加入 ListBox 『Peter 已存在!』而不會加入 ListBox 中。


8 4516628

資料的排序

  • 跟陣列一樣, ListBox 也提供排序資料的功能, 方法是將 ListBox 的Sorted 屬性設為 True。假設 ListBox1 原有的資料順序是 Peter、Jimmy、Thomas、Nick, 若將 ListBox1 的 Sorted 屬性設為 True,則資料將會依照字母順序排列, 成為 Jimmy、Nick、Peter、Thomas, 如下:


8 4 combobox

8-4 ComboBox (下拉式清單方塊)控制項

  • ComboBox (下拉式清單方塊) 是另一種特殊的 ListBox, 它是TextBox 與 ListBox 組合出來的控制項, 所以同時兼具 TextBox 的鍵盤輸入及 ListBox 的選單選取二種功能, 在操作介面的設計中,使用得十分廣泛。


Combobox

認識 ComboBox

  • ComboBox 是一個強化版的 ListBox, 以下請跟著筆者操作, 讓我們一起來認識 ComboBox。

  • 首先在表單上佈置一個 ( 請注意它跟 長得很像, 不要弄錯了), 然後利用 Items 屬性在這個ComboBox 中加入 Peter、Jimmy、Thomas、Nick、Philip 等 5 項資料。


Combobox1

認識 ComboBox

  • 加入資料後, 我們發現所加入的資料並未出現在這個ComboBox 上面, 如下圖, 所以試著把 ComboBox 拉高看看, 結果發現無法拉高:


Combobox2

認識 ComboBox

  • 執行程式, 然後以滑鼠按下 ComboBox 的下拉鈕, 結果出現一個下拉方塊, 其中列出了先前加入的所有資料, 如下:

  • 其實這一個下拉方塊就是 ListBox, 而且它的操作方式也跟前面介紹的 ListBox 相同。


Combobox3

認識 ComboBox

  • 拉下 ListBox, 點選其中的資料 ( 假設點選 Thomas), 則被點選的資料會出現在上面的 TextBox 欄位中, 如下:


Combobox4

認識 ComboBox

  • 以上的介紹突顯出 ComboBox 的一個特色:節省空間。當我們佈置一個 ComboBox 時, 它只佔用一個 TextBox 的大小, 而執行時,卻可以利用下拉鈕來選擇預先準備好的選項。


Combobox5

認識 ComboBox

  • 再次拉下 ListBox , 但不要用滑鼠點選資料, 按下[N] 、 鍵, 結果 “Nick”變成選項, 按下[P] 、 鍵, 結果 “Peter”變成選項..., 還有一點比較特別的是:選擇 “Philip”是按下[P] 、[H] 、 鍵, 因為 "P" 已經被用來選取 "Peter" 了。


Combobox6

認識 ComboBox

  • 從上面的操作中, 我們可以看出 ComboBox 不只是比 ListBox 多出一個 TextBox, 更重要的是 ComboBox 可以根據 TextBox 輸入的內容來搜尋資料。

  • 綜合前面的討論, 我們整理出 ComboBox 比較突出的特色:

    • 比 ListBox 多出下拉鈕及 TextBox。

    • 顯示時只佔用一個欄位, 比較節省空間。

    • 可以根據 TextBox 輸入的內容來搜尋資料, 減少操作時尋找資料的時間。


Combobox7

ComboBox 的『自動完成』功能

  • 在前面的示範中, 輸入文字後要按鍵, ComboBox 才會搜尋 ListBox的內容,並自動幫我們輸入搜尋到的資料項。其實 ComboBox 還具備了『自動完成』(AutoComplete) 的功能,例如當我們輸入 "P" 時:


Combobox8

ComboBox 的『自動完成』功能

  • 如果符合的選項很多, 那麼您可繼續輸入第 2、第 3 個字, 直到選出正確的資料為止。例如我們輸入 "P" 後再輸入 "h":


Combobox9

ComboBox 的『自動完成』功能

  • 要讓 ComboBox 具備『自動完成』功能, 首先要設定 AutoCompleteMode 屬性:


Combobox10

ComboBox 的『自動完成』功能


Combobox11

ComboBox 的『自動完成』功能

  • 設定好之後, ComboBox 就具備『自動完成』的功能了。


Combobox12

認識 ComboBox

  • 其實 TextBox 也具備『自動完成』功能, 只不過它沒有 ListBox 的清單項目可做為資料來源。此時可將其 AutoCompleteSource 屬性設為CustomSource, 然後再到 AutoCompleteCustomSource 屬性中按 鈕輸入所要使用的清單項目。


Combobox13

ComboBox 的三種樣式

  • 剛才介紹的 ComboBox 其實是一種叫做下拉式 (DropDown) 的ComboBox, 它包含三種成份:TextBox、下拉鈕、及 ListBox:


Combobox14

ComboBox 的三種樣式

  • 而透過 DropDownStyle 屬性的設定, 我們還可以將 ComboBox 的樣式設定成簡單式 (Simple)或下拉清單式 (DropDownList), 如下:


Combobox15

ComboBox 的三種樣式


Combobox16

ComboBox 的三種樣式

  • 在這 3 種樣式之中, 以 DropDown 樣式的功能最齊全, 而其他二種樣式則各缺一種功能。其實每種樣式各有不同的應用時機, 例如在VB 中的字型交談窗:


Combobox17

ComboBox 的三種樣式


Combobox18

ComboBox 的程式設計

  • 就像 ComboBox 是由 ListBox、TextBox、及下拉鈕所組成的一樣,其程式設計也可分成 ListBox、TextBox、及下拉鈕三部分。

  • 在 ListBox 方面, ComboBox 承龔了 ListBox 的主要特性, 所以ListBox 即有的屬性及方法大多適用於 ComboBox, 包含:


Combobox19

ComboBox 的程式設計


Combobox20

ComboBox 的程式設計

  • 在 TextBox 方面, 主要是利用 Text 屬性來存取其內容。

  • 在下拉鈕方面, 其『拉下』及『收起』可以由 DroppedDown屬性來控制:


Combobox21

ComboBox 的程式設計

  • 修改前面的字型設定程式 (Ch08-15), 以 ComboBox 取代 ListBox。


Combobox22

ComboBox 的程式設計

  • 請開啟範例專案 Ch08-20, 我們已準備好所需控制項:


Combobox23

ComboBox 的程式設計

  • 請分別將 3 個 ComboBox 設為 3 種不同的樣式(DropDownStyle), 如下:


Combobox24

ComboBox 的程式設計

  • 將 ComboBox1 及 ComboBox3 的 Text 屬性分別設為" 新細明體" 及 "12", 做為初值。ComboBox2 因是 DropDownList樣式 ( 只能由清單選取), 所以在屬性窗格中設定 Text 屬性不會有任何作用。


Combobox25

ComboBox 的程式設計

  • 當程式在執行時, ComboBox 的值還可以經由 Text、SelectedItem、或 SelectedIndex 屬性來讀取或設定。請在表單空白處雙按, 我們利用表單的 Load 事件來設定ComboBox2的初值:


Combobox26

ComboBox 的程式設計

  • 除了用 Text 屬性來指定之外, 您也可以改用『ComboBox2.SelectedItem = “標準”』或『ComboBox2.SelectedIndex = 0』來設定, 效果相同。

  • 建立 Button1.Click 事件程序:


Combobox27

ComboBox 的程式設計


Combobox28

ComboBox 的程式設計

  • 執行程式, 在 ComboBox1 ( 字型) 及 ComboBox3 ( 大小) 中以鍵盤輸入清單中沒有的值, 例如 “ 細明體” 及 “18”, 然後按設定字型測試看看。


Combobox29

ComboBox 的程式設計

無論使用者是由鍵盤輸入或由清單中選取, 所輸入的值都會儲存到Text 屬性中, 因此我們應該使用 Text 屬性來讀取 ComboBox 的值, 而不要用 SelectedItem, 因為後者可能是空值, 例如:


Combobox30

ComboBox 的程式設計

  • 除非限制使用者只能由清單中選取, 例如將 C o m b o B o x 設為 DropDownList 樣式, 這時才能安全地由 SelectedItem 或SelectedIndex 屬性來讀取使用者所選擇的資料。


Combobox31

ComboBox 的程式設計

  • 修改前面『可將輸入的資料加於 ListBox 中』的程式 (Ch08-19), 但將 TextBox 及 ListBox 改用 ComboBox 取代。

  • 建立 Windows Form 應用程式專案 Ch08-21。

  • 在表單中佈置如下的控制項:


Combobox32

ComboBox 的程式設計

  • 在 Button1.Click 事件程序中輸入以下程式:


Combobox33

ComboBox 的程式設計

  • 執行程式, 然後依序輸入 Peter、Jimmy、Thomas、Nick、Peter, 結果前 4 項資料都可以加入清單中, 但輸入第 5 項資料Peter 時, 會顯示『Peter 已存在!』而不會加入 ListBox 中。

    如果與使用 TextBox 及 ListBox 的資料輸入程式 (Ch08-19) 做比較, 您將會發現除了 TextBox1 及 ListBox1 都被換成 ComboBox1之外, 其他部分則是完全相同的。


  • Login