首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> C# >> 關於C#

C# WinForms 計算機完整教學:事件驅動、狀態管理與四則運算實作

     編輯:關於C#

建立一個標準四則運算計算機是學習 WinForms 事件驅動程式設計、狀態機制與 UI 邏輯分離的經典入門專案。本文完整提供介面配置、變數設計、按鈕事件處理、運算邏輯與完整可執行程式碼。

介面配置 (Form 設計器)

控制項NameText關鍵屬性
FormcalcForm計算機FormBorderStyle=FixedDialog, MaximizeBox=False
TextBoxtxtCalc(空)ReadOnly=True, RightToLeft=Yes, Font=Consolas 14pt
Buttonbtn0~btn90~9Size=32x32, Font=12pt
ButtonbtnDot.
ButtonbtnAdd+BackColor=Control, Height=80 (跨兩行)
ButtonbtnSub-
ButtonbtnMul×Text="*"
ButtonbtnDiv÷Text="/"
ButtonbtnEqu=Width=80, BackColor=Control
ButtonbtnClrACBackColor=Control

核心變數與狀態定義

public partial class CalcForm : Form
{
    private double _accumulator = 0;   // 運算數 A (累積結果)
    private double _current = 0;       // 運算數 B (目前輸入)
    private string _pendingOp = "=";   // 待執行運算子
    private bool _clearOnNextInput = true; // 是否清空畫面準備新輸入
    private bool _firstOperand = true; // 是否為第一個運算數

    public CalcForm() => InitializeComponent();
}

數字與小數點按鈕統一事件

private void NumberButton_Click(object sender, EventArgs e)
{
    if (_clearOnNextInput)
    {
        txtCalc.Clear();
        _clearOnNextInput = false;
    }

    Button btn = (Button)sender;
    string input = btn.Text;

    // 處理小數點:避免重複、開頭補 0
    if (input == ".")
    {
        if (txtCalc.Text.Contains(".")) return;
        if (string.IsNullOrEmpty(txtCalc.Text)) txtCalc.Text = "0";
    }

    txtCalc.Text += input;
    _current = double.Parse(txtCalc.Text);
}

設計器中將 btn0~btn9、btnDot 的 Click 事件全指向此方法。

運算子按鈕事件 (+, -, ×, ÷)

private void OperatorButton_Click(object sender, EventArgs e)
{
    Button btn = (Button)sender;
    string newOp = btn.Text; // "+", "-", "*", "/"

    if (!_firstOperand)
    {
        Calculate(); // 執行前一個待定運算
    }
    else
    {
        _accumulator = _current;
        _firstOperand = false;
    }

    _pendingOp = newOp;
    _clearOnNextInput = true; // 下一個數字輸入時清空畫面
}

等號按鈕事件

private void btnEqu_Click(object sender, EventArgs e)
{
    Calculate();
    _pendingOp = "=";
    _firstOperand = true; // 重置狀態,準備新計算
}

核心計算邏輯


private void Calculate()
{
    switch (_pendingOp)
    {
        case "+": _accumulator += _current; break;
        case "-": _accumulator -= _current; break;
        case "*": _accumulator *= _current; break;
        case "/":
            if (_current == 0)
            {
                txtCalc.Text = "Error: Div by 0";
                _accumulator = 0;
                _firstOperand = true;
                return;
            }
            _accumulator /= _current;
            break;
        case "=": // 重複等號:再次執行相同運算
            break;
    }

    txtCalc.Text = _accumulator.ToString("G15"); // 避免科學記號,保留精度
    _current = _accumulator; // 為連續運算準備
}

清除按鈕 (AC)

private void btnClr_Click(object sender, EventArgs e)
{
    _accumulator = 0;
    _current = 0;
    _pendingOp = "=";
    _firstOperand = true;
    _clearOnNextInput = true;
    txtCalc.Clear();
    txtCalc.Focus();
}

完整程式碼 (CalcForm.cs)

using System;
using System.Windows.Forms;

namespace WinCalc
{
    public partial class CalcForm : Form
    {
        private double _acc = 0, _cur = 0;
        private string _op = "=";
        private bool _clearNext = true, _first = true;

        public CalcForm() { InitializeComponent(); }

        private void Num_Click(object s, EventArgs e)
        {
            if (_clearNext) { txtCalc.Clear(); _clearNext = false; }
            var b = (Button)s;
            if (b.Text == ".") { if (txtCalc.Text.Contains(".")) return; if (txtCalc.Text == "") txtCalc.Text = "0"; }
            txtCalc.Text += b.Text;
            _cur = double.Parse(txtCalc.Text);
        }

        private void Op_Click(object s, EventArgs e)
        {
            var b = (Button)s;
            if (!_first) Calc(); else _acc = _cur;
            _op = b.Text; _first = false; _clearNext = true;
        }

        private void Eq_Click(object s, EventArgs e) { Calc(); _op = "="; _first = true; }

        private void Calc()
        {
            switch (_op)
            {
                case "+": _acc += _cur; break;
                case "-": _acc -= _cur; break;
                case "*": _acc *= _cur; break;
                case "/": if (_cur == 0) { txtCalc.Text = "Error"; _acc = 0; _first = true; return; } _acc /= _cur; break;
            }
            txtCalc.Text = _acc.ToString("G15");
            _cur = _acc;
        }

        private void Clr_Click(object s, EventArgs e)
        {
            _acc = _cur = 0; _op = "="; _first = true; _clearNext = true;
            txtCalc.Clear(); txtCalc.Focus();
        }
    }
}

進階擴充建議

  • 鍵盤支援:覆寫 ProcessCmdKey 捕捉 Keys.NumPad0~Keys.Divide 觸發對應按鈕 PerformClick()。
  • 歷史紀錄:加入 ListBox 記錄每次計算式與結果。
  • 科學模式:擴充 sin, cos, sqrt, % 等單元運算子。
  • BigInteger/Decimal:避免 double 浮點誤差,金融計算請用 decimal。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved