C# 是 .NET Framework 的核心開發語言,配合 System.Windows.Forms 命名空間可快速建立桌面應用程式。本文以「攝氏/華氏溫度轉換器」為例,完整示範 WinForms 開發的三大步驟:建立表單、配置控制項、撰寫事件處理邏輯。
csc.exe),或 Visual Studio .NET繼承 System.Windows.Forms.Form,在建構子中設定視覺屬性:
public class TempConverter : System.Windows.Forms.Form
{
public TempConverter()
{
// 視窗尺寸與行為
this.ClientSize = new System.Drawing.Size(180, 90);
this.FormBorderStyle = FormBorderStyle.FixedDialog;
this.Text = "°C → °F / °F → °C";
this.StartPosition = FormStartPosition.CenterScreen;
this.MaximizeBox = false;
this.HelpButton = false;
}
[STAThread]
public static void Main()
{
Application.Run(new TempConverter());
}
}
編譯指令:
csc /r:System.dll /r:System.Windows.Forms.dll /r:System.Drawing.dll TempConverter.cs
宣告欄位、實例化、設定屬性、加入 Controls 集合:
public class TempConverter : System.Windows.Forms.Form
{
// 控制項欄位
private Label lblC = new Label();
private Label lblF = new Label();
private TextBox txtC = new TextBox();
private TextBox txtF = new TextBox();
private Button btnCtoF = new Button();
private Button btnFtoC = new Button();
public TempConverter()
{
// ... 表單屬性設定同上 ...
// 攝氏輸入區
txtC.TabIndex = 0; txtC.Size = new Size(50, 25); txtC.Location = new Point(13, 5);
lblC.TabStop = false; lblC.Text = "°C"; lblC.Size = new Size(25, 25); lblC.Location = new Point(65, 5);
// 華氏輸入區
txtF.TabIndex = 1; txtF.Size = new Size(50, 25); txtF.Location = new Point(90, 5);
lblF.TabStop = false; lblF.Text = "°F"; lblF.Size = new Size(25, 25); lblF.Location = new Point(142, 5);
// 轉換按鈕
btnCtoF.TabIndex = 2; btnCtoF.Text = "°C → °F"; btnCtoF.Size = new Size(70, 25); btnCtoF.Location = new Point(13, 35);
btnFtoC.TabIndex = 3; btnFtoC.Text = "°F → °C"; btnFtoC.Size = new Size(70, 25); btnFtoC.Location = new Point(90, 35);
// 事件訂閱
btnCtoF.Click += new EventHandler(btnCtoF_Click);
btnFtoC.Click += new EventHandler(btnFtoC_Click);
// 加入表單
this.Controls.AddRange(new Control[] { txtC, lblC, txtF, lblF, btnCtoF, btnFtoC });
}
// ... 事件處理方法見下節 ...
}
private void btnCtoF_Click(object sender, EventArgs e)
{
if (!double.TryParse(txtC.Text, out double c))
{
txtC.Clear(); txtF.Clear();
return;
}
double f = 1.8 * c + 32;
txtF.Text = f.ToString("F2"); // 保留兩位小數
txtF.Focus();
txtF.Select(0, 0); // 游標移至開頭
}
private void btnFtoC_Click(object sender, EventArgs e)
{
if (!double.TryParse(txtF.Text, out double f))
{
txtC.Clear(); txtF.Clear();
return;
}
double c = (f - 32) / 1.8;
txtC.Text = c.ToString("F2");
txtC.Focus();
txtC.Select(0, 0);
}
using System;
using System.Windows.Forms;
public class TempConverter : Form
{
private Label lblC = new Label(), lblF = new Label();
private TextBox txtC = new TextBox(), txtF = new TextBox();
private Button btnCtoF = new Button(), btnFtoC = new Button();
public TempConverter()
{
ClientSize = new Size(180, 90);
FormBorderStyle = FormBorderStyle.FixedDialog;
Text = "°C → °F / °F → °C";
StartPosition = FormStartPosition.CenterScreen;
MaximizeBox = false; HelpButton = false;
txtC.TabIndex = 0; txtC.Size = new Size(50, 25); txtC.Location = new Point(13, 5);
lblC.TabStop = false; lblC.Text = "°C"; lblC.Size = new Size(25, 25); lblC.Location = new Point(65, 5);
txtF.TabIndex = 1; txtF.Size = new Size(50, 25); txtF.Location = new Point(90, 5);
lblF.TabStop = false; lblF.Text = "°F"; lblF.Size = new Size(25, 25); lblF.Location = new Point(142, 5);
btnCtoF.TabIndex = 2; btnCtoF.Text = "°C → °F"; btnCtoF.Size = new Size(70, 25); btnCtoF.Location = new Point(13, 35);
btnFtoC.TabIndex = 3; btnFtoC.Text = "°F → °C"; btnFtoC.Size = new Size(70, 25); btnFtoC.Location = new Point(90, 35);
btnCtoF.Click += btnCtoF_Click;
btnFtoC.Click += btnFtoC_Click;
Controls.AddRange(new Control[] { txtC, lblC, txtF, lblF, btnCtoF, btnFtoC });
}
[STAThread]
static void Main() => Application.Run(new TempConverter());
private void btnCtoF_Click(object sender, EventArgs e)
{
if (!double.TryParse(txtC.Text, out double c)) { txtC.Clear(); txtF.Clear(); return; }
txtF.Text = (1.8 * c + 32).ToString("F2");
txtF.Focus(); txtF.Select(0, 0);
}
private void btnFtoC_Click(object sender, EventArgs e)
{
if (!double.TryParse(txtF.Text, out double f)) { txtC.Clear(); txtF.Clear(); return; }
txtC.Text = ((f - 32) / 1.8).ToString("F2");
txtC.Focus(); txtC.Select(0, 0);
}
}
| 概念 | 說明 |
|---|---|
| 繼承 Form | 所有視窗基類,提供視覺容器與訊息迴圈 |
| Controls 集合 | 管理子控制項的版面配置與生命週期 |
| 事件訂閱 (+=) | 將委派方法連結至控制項事件 |
| TryParse 模式 | 安全轉換使用者輸入,避免例外拋出 |
| Application.Run | 啟動訊息迴圈,進入應用程式主迴圈 |
TableLayoutPanel 或 FlowLayoutPanel 取代絕對座標,支援 DPI 縮放與多語系。ErrorProvider 顯示輸入驗證錯誤圖示。TemperatureConverter),符合單一職責原則。INotifyPropertyChanged 實現 MVVM 風格架構。