--- tags: 110-2視窗程式設計 --- # 實作:單位轉換程式(程式撰寫) 接下來,我們要開始進行程式的撰寫,其實之前就提及了,寫程式是「**設計一個資料處理的流程**」。因此我們這個長度轉換程式要設計什麼樣的「工作流程」?很簡單: :::info 1. 長度單位計算:選擇任一種長度單位的輸入文字框,輸入數字,然後其他單位的輸入文字框會顯示轉換結果 2. 清除功能:點選「清除」按鍵,會清除掉所有輸入文字框的內容 3. 訊息顯示:如果有錯誤的訊息,會顯示在說明文字的輸入文字框 ::: 所以以下我們依照上述的流程,一一將程式內容設計出來。 :::success 別忘了,你可以隨時對專案進行「Commit」 ::: ## 長度轉換公式 首先我們先確定一下,長度單位的轉換公式是什麼?大致如下: 1. 公制單位比較簡易一點,而且我們生活中也很常用,「1公分=0.01公尺=0.001公里」,或者,「1公里=1,000公尺=100,000公分」 2. 英吋我們少用,但也先把它寫出來,1英吋=2.54公分,1英碼=3英呎=36英吋 為了簡化起見,我們先做公制單位的,熟悉之後,我們再寫英制的。 ## 事件綁定 接下來算是一個很重要的概念,這個瞭解了,你才能把「設計好的介面」,連結到「程式內容」。 也就是說,我們需要「**捕捉特定的事件**」,也就是說要先設定好:如果使用者做了特定的事情,程式就要做出特定的動作。 :::info 當使用者按下特定按鍵、在輸入文字框輸入文字、關閉視窗、移動滑鼠游標...這些都是所謂的「事件」 ::: 我們這邊學習[範例網站](http://www.mold.net.tw/classroom/unit.htm)的作法,你可以再試用看看,請你仔細觀察:什麼樣的事件發生時,就會做長度單位的轉換? 也就是:==使用者輸入數字後,就會進行長度轉換。== 這邊跟同學說明,通常,使用者在視窗上面做任何事情,大概都會預設各種基本事件可用,例如:Click 事件,通常就是指使用者點選滑鼠按鍵的事件、Double Click 事件,就是連點兩下滑鼠按鍵的事件。 因此在微軟的視窗程式中也不例外,使用者在鍵盤上按下按鍵,通常就是「**KeyDown 與 KeyUp 事件**」,其中,KeyDown 指的是「**按下按鍵的瞬間**」,KeyUp 則是「**放開按鍵的瞬間**」,你可以發現到,一個普通按下鍵盤按鍵的動作,其實可以被分成兩個階段,而且順序是「KeyDown」->「KeyUp」。 所以我們選擇使用「KeyUp」事件,因為使用者按下按鍵最後的動作是「KeyUp」事件,亦即在 KeyUp 階段我們可以確定使用者到底輸入什麼樣的東西?也就是說... :::info 我們要捕捉到使用者按下按鍵的事件,綁定它,讓這個事件發生後,讓程式做出相對應的動作。 ::: ## 開始寫程式 現在終於可以開始寫程式了,我們大概把整個流程整理如下: :::success 1. 使用者在輸入文字框中按下按鍵後,我們要能夠偵測這個事情的發生 2. 然後根據輸入文字框內容,寫程式做單位轉換 3. 把單位轉換後的結果,顯示到其他長度單位的輸入文字框中 ::: 首先我們設定特定的控制項,設定「當使用者在上面用鍵盤輸入時」,偵測「KeyUp」事件,那怎麼做這個設定呢? 我們先從「公分」的「輸入文字框」設定「KeyUp」事件,請找到「txtCM」輸入文字框。  再到「屬性視窗」設定事件綁定,請先選擇一個有著閃電符號的按鍵,就會列出這個控制項可以設定的各種事件,你可以發現可以設定的事件相當多,請找到「**KeyUp**」事件,在旁邊的欄位連點兩下。  連點兩下之後,就會出現一段程式碼。  這樣你就已經綁定好使用者按下按鍵的事件,之後就要在上面的程式碼區段,撰寫使用者按下按鍵後,要程式做的事情。 :::info 視窗程式的撰寫,事件綁定是最常見的,你只要能夠設定好正確的事件綁定,就成功一半了。 ::: 程式該寫什麼呢?請參考以下的內容,將程式碼3-8行複製貼上到以上的區塊。 ```csharp= private void txtCM_KeyUp(object sender, EventArgs e) { double douCM; //宣告一個double變數,變數名稱叫douCM douCM = Convert.ToDouble(txtCM.Text); //從txtCM輸入文字框取得輸入的文字,並且轉換成double的資料型態 txtM.Text = string.Format("{0:0.##########}", douCM / 100); //將douCM的數值除以100,也就是從公分轉換成公尺 //透過string.Format格式化成小數點後共10位的數字,轉型成文字型態,在txtM顯示結果 } ``` 複製貼上之後,請測試程式,你應該可以發現,在公分的輸入文字框輸入任何數字,都能轉換成公尺的單位。  ## 程式說明 接下來我們要稍微說明程式的內容,如同以下的程式碼: ```csharp= private void txtCM_KeyUp(object sender, EventArgs e) { double douCM; //宣告一個double變數,變數名稱叫douCM douCM = Convert.ToDouble(txtCM.Text); //從txtCM輸入文字框取得輸入的文字,並且轉換成double的資料型態 txtM.Text = string.Format("{0:0.##########}", douCM / 100); //將douCM的數值除以100,也就是從公分轉換成公尺 //透過string.Format格式化成小數點後共10位的數字,轉型成文字型態,在txtM顯示結果 } ``` 程式的說明如下。 :::success 當使用者在一個名為txtCM的文字框中輸入資料,並且釋放鍵盤按鍵時觸發。 輸入的資料是「以公分為單位」的數值,再轉換成「以公尺為單位」的數值,數值會顯示在另一個文字框txtM中。 ::: ### C# 變數宣告 你可能之前學電腦程式都有學過怎麼**宣告變數**。這裡不僅是給你複習,也希望讓你知道為什麼寫程式要宣告變數? 想想看,假如要計算「1 + 2 = 3」,如果你是人類,對你來說就是直接計算「1 + 2」,你腦海中就會得到答案「3」。 可是在電腦裡面不能這樣直接算,你要先告訴電腦說:要在電腦記憶體中設定一個空間A,放置數字1,再設定另一個記憶體空間B,放置數字2,再告訴電腦,這兩個記憶空間的資料要相加,然後「再」存到另一個記憶體空間C。  當然,這是簡化再簡化的講法,這是為了要讓同學理解,如果想要更深入理解電腦如何儲存資料,可以看[這裡](https://medium.com/starbugs/%E8%BA%AB%E7%82%BA-js-%E9%96%8B%E7%99%BC%E8%80%85-%E4%BD%A0%E4%B8%8D%E8%83%BD%E4%B8%8D%E7%9F%A5%E9%81%93%E7%9A%84%E8%A8%98%E6%86%B6%E9%AB%94%E7%AE%A1%E7%90%86%E6%A9%9F%E5%88%B6-d9db2fd66f8)。 :::success **「變數」主要是在扮演「儲存資料」的角色** ::: 所有的變數在使用之前,都必須先宣告過一遍,宣告的意思是讓電腦知道變數的「名稱」與「資料型態」是甚麼? :::info 1. **變數名稱**:顧名思義,每一個變數都不一樣,你要先告訴電腦你的變數叫甚麼名字?變數名稱你可以任意取名,但是第一個字元不能是數字,也不能是符號,唯一可用的符號是底線(_) 2. **資料型態(又稱為型別)**:也就是資料的格式是甚麼?數字?文字?還是一連串的數字或文字?這會關係到電腦如何幫你在記憶體配置空間。 ::: 以下是一個最簡單的變數宣告程式碼: ```csharp= int age = 30; ``` 程式說明: :::danger * 「age」:是變數名稱 * 「int」:意思是設定age這個變數,是一個整數的資料型態 * 「=」:等於符號意指,在等於符號後面的數值,要指定給age變數,換句話說,就是數值要置放到一個記憶體空間,那個記憶體空間名稱叫做age * 「30」:是你要設定給這個變數的資料 * 「;」:分號是一個C#程式結尾,代表在這一行中,程式結束在這裡。 ::: 因此變數宣告,也就是告知電腦到底我們要存甚麼樣子的資料?從而給這個變數多少記憶體空間(從資料型態判斷)以及它的名稱是甚麼?由於變數所儲存的資料是可以被改變的,在使用變數之前,務必先存入某個數值。如果沒有這樣做,電腦不會讓你編譯它。 ### 資料型態 剛剛我們介紹甚麼是變數宣告,其中除了「**變數名稱**」外,還要設定「**資料型態**」,也就是資料的格式是甚麼? 在 C# 的資料型態[很多種](https://ithelp.ithome.com.tw/m/articles/10213219),不過我們簡化課程起見,這裡只介紹最常使用的「布林」、「整數」、「浮點數」與「字串」。 |類型|關鍵字|說明| |--------|--------|--------| |布林|bool|也就是「真」與「假」,在程式裡面寫作「true」與「false」,也可以是「0」與「1」。| |整數|int|沒有小數點的正負數字。| |浮點數|float|有小數點的正負數字。特別注意需要在數字後面加上「f」。| |字串|string|一連串的文字符號,可以是英文字母、中文字符、符號(少部分則是要調整)。| 以下則是程式碼範例: ```csharp= // 布林型態 bool isReady = true; // 整數型態 int age = 30; // 浮點數型態 float pi = 3.14f; // 字串型態 string name = "John Smith"; ``` ### 資料型態轉換(轉型) 你可能會好奇,尤其是第5行的程式碼,為什麼要轉換呢?以下就要說明「**資料型態轉換(以下簡稱轉型)**」的概念。 在講轉型之前,要先說明什麼是「**資料型態**」,可能有的同學修過一年級程式設計後,這觀念還不是很清楚,希望這邊可以讓同學好好建立觀念。 大家應該都知道要寫程式處理資料,一定要先宣告變數,例如以下最簡單的程式碼: ```csharp= double douCM; ``` :::success 以上的程式碼很簡單,就是「宣告一個型態 double 的變數,變數名稱叫 douCM」。 ::: 其實,變數就像是一個空箱子,你要把資料存進去,就像是把一個東西放到這個空箱子裡面,之後我們要取出或處理這個資料,只要直接指定這個箱子的名稱,就能處理這個資料,資料就能夠隨時變動、計算或轉換,不需要直接處理這個資料。 不過,資料有很多種類型,有數字、文字、有小數點的數字、陣列等等,而且還有長度上的差別,越長的數字或文字,你需要更大的資料類型來儲存,這就是「資料型態」的概念。 那為什麼程式不能夠通通一起處理,需要分這麼多種資料類型? 原因很簡單,不同類型的資料你需要用不同的編碼方式來存成二進位資料(計算機概論的基礎知識),所以程式設計中需要設計不同的資料型態,來儲存各種資料。 上述的程式碼,我們設定的資料型態叫做「double」,其實這是一種「**浮點數**」資料型態,也就是具有小數點的數字,在 C# 中可以區分為 float、double 與 decimal 這三種,差別在精確度,float 精確度最低,decimal 精確度最高(但是相對需要更多記憶體),由於我們要做一般的數學計算,所以我們使用 double 就好。如果你要更精確,可以使用 decimal。 :::info 如果你想進一步瞭解浮點數資料型態,可以看[這裡](https://docs.microsoft.com/zh-tw/dotnet/csharp/language-reference/builtin-types/floating-point-numeric-types)。 ::: 現在我們已經設定一個浮點數的變數,所以還要把資料放進去,才能做進一步的計算,所以請同學再看下一段的程式碼。 ```csharp= douCM = Convert.ToDouble(txtCM.Text); ``` :::success 這是一個將 txtCM 輸入文字框中的內容取出,轉換成 double 資料型態,再存進 douCM 變數的過程。 ::: 你可能會問為什麼要這麼做呢?為什麼不是直接把輸入文字框的資料直接存進去? 其實電腦沒有這麼厲害,你沒有告訴它要先把「文字」轉換成「浮點數」,它就無法順利的將文字資料存到一個浮點數資料型態的變數裡面。所以我們使用「==Convert.ToDouble==」,將刮號裡面的文字資料轉換成浮點數的資料型態,然後再指定給 douCM 這個變數裡面。 這個就是轉型的概念,由於電腦程式實際上都是在處理各種資料,因此你會需要時常進行轉型的工作,才能順利的處理資料的轉換、計算。我們再看第三段程式碼。 ### 文字格式化 ```csharp= txtM.Text = string.Format("{0:0.##########}", douCM / 100); ``` :::success 將 douCM 的數值除以 100,也就是從公分轉換成公尺。 然後透過 string.Format 將 douCM 的數字,格式化成小數點後共 10 位的數字,最後轉型成文字後,在 txtM 輸入文字框顯示結果。 ::: 由於我們要計算將公分轉換成公尺,所以要把公分的數值,除以 100,才會得到公尺的數值。 得到公尺的數值後,因為數值仍然是 double 的型態,要在公尺的輸入文字框顯示,就要再轉型成文字的資料型態才行(就是這麼麻煩,但希望同學要習慣),這邊我們使用「==string.Format==」,這是一個將刮號內的資料轉換成文字型態,並且進一步「格式化」的方法。 「==string.Format==」需要兩個參數,第一個是「格式化的樣式」,第二個是要轉換的資料。 ```csharp string.Format("你設定的樣式", 要轉換的資料); ``` 什麼又叫「格式化」呢?其實就是將原始資料轉換成你希望呈現的樣式,這裡我們希望顯示的數字是「到小數點後第十位的數字」 格式化的方式很多,其實網路上可以找到各式各樣的用法,你可以格式化數字、日期、金額、百分比、電話號碼等等,例如你可以參考這個[網站](https://goodlucky.pixnet.net/blog/post/30233497-%5Bc%23%5D-string.format%E8%BC%B8%E5%87%BA%E6%A0%BC%E5%BC%8F)。 我們這邊用很簡單的:格式化成為小數點後共 10 位的數字,意思就是說,不管什麼樣的數字,如果有小數點,最多就是四捨五入到小數點後第十位。寫法如下: ```csharp {0:0.##########} ``` 其中第一個 0 代表從第一位數字開始,格式則是在冒號後面,我們設定的樣子就是「0.##########」,如果我們輸入一個數字是 0.12345678905,最終格式化後的數字就是 0.1234567891。 ## 移除控制項和事件綁定 有的時候你會發現類似以下的問題,一不小心,就讓整個設計的視窗畫面跑掉了...這樣的問題可能是因為你不小心把事件綁定的程式碼刪除。  假如你不小心按下「忽略並繼續」,又按下「是」會更糟糕,像這樣...你設計的畫面全部沒了!   如何解決呢,請依照以下的做法。請不要立刻按下「忽略並繼續」,點選黃色框選的地方。  然後你會看到類似以下的畫面,你應該注意到選起來的程式碼,那一行的程式碼結尾有紅色的波浪線條,說明那一段是有問題的,你可以直接刪掉那一行,記得要存檔。  存檔之後,你的視窗設計就會正常顯示了。  ### 比較好的方式 不過通常如果們要取消某一個控制項的事件綁定,最好要這樣做 ... 這時我們回到之前說過的事件綁定方式。例如下圖。  假設你希望把 KeyUp 所綁定的事件移除,請直接把「txtCM_KeyUp」刪除,這時你就可以把以下黃框部分的程式碼給刪除。  這樣的做法就不容易出現錯誤,不過有的時候你可能還是會發生前述的狀況,屆時就可以用前述的方式來解決。 ### 如果還是不小心讓視窗介面消失了... 例如像下面的情況 ... 別擔心,這也可以解決,不過稍微要看仔細一點。  這時請開啟方案總管視窗,並且找到版面設計檔「Form1.cs」所屬的介面設定程式碼「Form1.Designer.cs」檔案,點兩下開啟它。我們所看到的視窗介面,其實就是這個檔案中的程式碼所形成。當你拖拉一個控制項進去,其實就是 Visual Studio 自動幫你產生這個程式碼到這個檔案去。  「Form1.Designer.cs」檔案點兩下開啟它之後,你會看到類似前面所述的程式碼,請你點開「Windows Form 設計工具所產生的程式碼」。  然後你會看到類似以下的畫面,也是以同樣的方式直接刪掉那一行有紅色波浪線的程式碼,記得要存檔。這樣就可以解決問題了!  ## 結語 現在完成基本的程式撰寫後,你按測試(或快速鍵F5),應該就可以初步執行這隻單位轉換程式。 不過,你應該會發現到一些問題...。
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up