通り*さん投稿の電卓アプリです。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace ToyCalc
{
    /// <SUMMARY>
    /// 画面
    /// </SUMMARY>
    public partial class Form1 : Form
    {
        private ToyCalc _Calc;
        public Form1()
        {
            InitializeComponent();
            // 電卓表示
            InitToyCalcForm();
            // 計算結果はフォームのタイトルへ表示する
            // (バインド方法は、とりこびとさんのエントリで勉強させてもらいました)
            _Calc = new ToyCalc();
            this.DataBindings.Add("Text", _Calc, "ValueForDisplay", false, DataSourceUpdateMode.OnPropertyChanged);
        }
        /// 
        /// 電卓表示
        /// 
        private void InitToyCalcForm()
        {
            this.Size = new Size(200, 200);
            // ボタンをレイアウトするためのパネルの準備
            TableLayoutPanel tlp = new TableLayoutPanel();
            tlp.ColumnCount = 4;
            for (int i = 0; i < tlp.ColumnCount; i++)
                tlp.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100f / tlp.ColumnCount));
            tlp.RowCount = 5;
            for (int i = 0; i < tlp.RowCount; i++)
                tlp.RowStyles.Add(new RowStyle(SizeType.Percent, 100f / tlp.RowCount));
            tlp.AutoSize = true;
            tlp.Dock = DockStyle.Fill;
            this.Controls.Add(tlp);
            // 表示するボタンの順番
            ToyCalcButtons[] buttons =
            {
                ToyCalcButtons.Clear, ToyCalcButtons.ClearEntry, ToyCalcButtons.Divide, ToyCalcButtons.Multiply,
                ToyCalcButtons.Seven, ToyCalcButtons.Eight, ToyCalcButtons.Nine, ToyCalcButtons.Subtract,
                ToyCalcButtons.Four, ToyCalcButtons.Five, ToyCalcButtons.Six, ToyCalcButtons.Add,
                ToyCalcButtons.One, ToyCalcButtons.Two, ToyCalcButtons.Three, ToyCalcButtons.Equal,
                ToyCalcButtons.Zero
            };
            string[] buttonCaptions =
            {
                "C", "CE", "÷", "×",
                "7", "8", "9", "-",
                "4", "5", "6", "+",
                "1", "2", "3", "=",
                "0"
            };
            // ボタンを生成
            Button b;
            for (int i = 0; i < buttons.Length; i++)
            {
                b = new Button();
                b.Dock = DockStyle.Fill;
                b.Text = buttonCaptions[i];
                b.Tag = buttons[i];
                // (匿名メソッドの存在をすっかり忘れていましたが、エピさんのソースを拝見して思い出しました)
                b.Click += delegate(object sender, eventArgs e) { _Calc.Push((ToyCalcButtons)((Button)sender).Tag); };
                tlp.Controls.Add(b);
            }
            // コピーボタンが押されたら、表示内容をクリップボードへ貼り付ける
            b = new Button();
            b.Dock = DockStyle.Fill;
            b.Text = "コピー";
            b.Click += delegate { Clipboard.SetText(this.Text); };
            tlp.Controls.Add(b);
        }
    }
    /// 
    /// 各ボタンを表す列挙型
    /// 
    public enum ToyCalcButtons
    {
        // Zero~Nineは数値にキャストして使います
        Zero = 0, One, Two, Three, Four, Five, Six, Seven, Eight, Nine,
        Clear, ClearEntry,
        Add, Subtract, Multiply, Divide,
        Equal
    }
    /// 
    /// おもちゃ計算機
    /// 
    public class ToyCalc : INotifyPropertyChanged
    {
        // 変数達(絶対どれかいらなさそう...)
        private decimal _Result;
        private decimal _CurrValue;
        private decimal _LastValue;
        private ToyCalc _Stack;
        private ToyCalcButtons _LastPushed;
        private ToyCalcButtons _PrevPushed;
        private ToyCalcButtons _PrevOperator; // Equal は設定されない
        private bool _PrevOperatorIsEqual;    // Equal はこちらで判定する
        private bool _PrevOperatorIsValid;
        private string _ErrorReason;
        public ToyCalc()
        {
            // まずクリア!
            Push(ToyCalcButtons.Clear);
        }
        /// 
        /// ボタンが押されたときの処理
        /// 
        public void Push(ToyCalcButtons button)
        {
            // エラー状態の場合はクリアしかできません
            if (_ErrorReason != "" && button != ToyCalcButtons.Clear)
                return;
            
            if (IsInStack(button)) return;
            _LastPushed = button;
            switch (getButtonTypeOf(button))
            {
                case ButtonType.Clear:
                    // クリア!
                    Clear(button == ToyCalcButtons.ClearEntry);
                    break;
                case ButtonType.Num:
                    // 数字ボタンの処理
                    if (_PrevPushed == ToyCalcButtons.Equal)
                        _Result = 0;
                    BuildCurrValue(button);
                    break;
                case ButtonType.Operator:
                    // 演算子ボタンの処理
                    Calculate(button);
                    break;
            }
            _PrevPushed = _LastPushed;
        }
        /// 
        /// スタックでの計算に関する処理
        /// 
        /// <returns>スタックに計算を任せた場合、truereturns>
        private bool IsInStack(ToyCalcButtons button)
        {
            if (_Stack == null && !_PrevOperatorIsEqual)
            {
                switch (button)
                {
                    case ToyCalcButtons.Multiply:
                    case ToyCalcButtons.Divide:
                        if (_PrevOperatorIsValid)
                        {
                            // "+*" への対処。"+" でいったん計算が確定するので、スタックには入らないように
                            switch (_PrevPushed)
                            {
                                case ToyCalcButtons.Add:
                                case ToyCalcButtons.Subtract:
                                    return false;
                            }
                            // "1+2*"の場合、"2"のところから別ので計算してもらう
                            switch (_PrevOperator)
                            {
                                case ToyCalcButtons.Add:
                                case ToyCalcButtons.Subtract:
                                    // もう一つ生成
                                    _Stack = new ToyCalc();
                                    // "2*" の "*" でここへ来るので、"2" をセットしておく
                                    if (getButtonTypeOf(_PrevPushed) == ButtonType.Num)
                                        _Stack._CurrValue = this._CurrValue;
                                    _Stack.PropertyChanged += new PropertyChangedeventHandler(_Stack_PropertyChanged);
                                    break;
                            }
                        }
                        break;
                }
            }
            if (_Stack != null)
            {
                switch (button)
                {
                    case ToyCalcButtons.Clear:
                        _Stack = null;
                        break;
                    case ToyCalcButtons.Add:
                    case ToyCalcButtons.Subtract:
                        // "1+2*+" は "1+2*[2]+" と解釈しないで、"*" が "+" に訂正されたと見なします
                        if (getButtonTypeOf(_Stack._PrevPushed) != ButtonType.Num)
                            _Stack._LastPushed = ToyCalcButtons.Equal;
                        // 後は "=" と同じ処理
                        goto case ToyCalcButtons.Equal;
                    case ToyCalcButtons.Equal:
                        // スタックから計算結果をもらう
                        _CurrValue = _Stack.Result;
                        _Stack = null;
                        break;
                }
            }
            if (_Stack != null)
            {
                // スタックに処理してもらう
                _Stack.Push(button);
                _ErrorReason = _Stack._ErrorReason;
                return true;
            }
            return false;
        }
        /// 
        /// クリア!
        /// 
        private void Clear(bool onlyCurrentEntry)
        {
            _CurrValue = 0m;
            _LastValue = 0m;
            if (!onlyCurrentEntry)
            {
                _Result = 0m;
                _Stack = null;
                // (最初の入力値は 0+N になるように初期値を Add にしておきます)
                _PrevOperator = ToyCalcButtons.Add;
                _PrevOperatorIsValid = false;
                _PrevOperatorIsEqual = false;
                _ErrorReason = "";
            }
            // バインド先の値が更新されますように...
            NotifyPropertyChanged("ValueForDisplay");
        }
        /// 
        /// 数字ボタンの処理
        /// 
        private void BuildCurrValue(ToyCalcButtons button)
        {
            try
            {
                checked // ←decimalだといらないみたい?
                {
                    _CurrValue = _CurrValue * 10m + (decimal)button;
                }
            }
            catch (OverflowException)
            {
                System.Media.SystemSounds.Beep.Play();
            }
            _LastValue = _CurrValue;
            NotifyPropertyChanged("ValueForDisplay");
        }
        /// 
        /// +や*などの処理
        /// 
        private void Calculate(ToyCalcButtons button)
        {
            bool through = false;
            if (button == ToyCalcButtons.Equal)
            {
                if (_PrevOperatorIsValid)
                {
                    // "1+2==" を "1+2=3[+2]=" として処理
                    if (_PrevOperatorIsEqual)
                        _CurrValue = _LastValue;
                    // "1+2*3*=" を "1+2*3*[2*3]=" として処理
                    else if (getButtonTypeOf(_PrevPushed) != ButtonType.Num)
                        _CurrValue = _Result;
                }
            }
            else
            {
                // "*+" の場合、訂正とみなして前の演算子は無視
                // (ただし "+*" の場合、"+" は無視しない)
                through =
                    _PrevPushed == ToyCalcButtons.Multiply
                    || _PrevPushed == ToyCalcButtons.Divide
                    || _PrevPushed == ToyCalcButtons.Equal;
            }
            if (!through)
            {
                try
                {
                    checked
                    {
                        // "1+2-" の "-" 時点で "1+2" を行うので、一つ前の演算子で計算する
                        switch (_PrevOperator)
                        {
                            case ToyCalcButtons.Add:
                                _Result += _CurrValue;
                                break;
                            case ToyCalcButtons.Subtract:
                                _Result -= _CurrValue;
                                break;
                            case ToyCalcButtons.Multiply:
                                _Result *= _CurrValue;
                                break;
                            case ToyCalcButtons.Divide:
                                _Result /= _CurrValue;
                                _Result = decimal.Floor(_Result);
                                break;
                            default:
                                throw new Exception("不明な演算子");
                        }
                    }
                }
                catch (DivideByZeroException)
                {
                    _ErrorReason = "ゼロ除算エラー";
                }
                catch (OverflowException)
                {
                    // アンダーフローもここ
                    _ErrorReason = "オーバーフロー";
                }
                _LastValue = _CurrValue;
                _CurrValue = 0m;
                NotifyPropertyChanged("ValueForDisplay");
            }
            if (button != ToyCalcButtons.Equal)
            {
                _PrevOperator = button;
                _PrevOperatorIsValid = true;
                _PrevOperatorIsEqual = false;
            }
            else
                _PrevOperatorIsEqual = true;
        }
        /// 
        /// 表示用の値
        /// 
        public string ValueForDisplay
        {
            get
            {
                if (_ErrorReason != "")
                    return _ErrorReason;
                decimal value;
                if (_Stack == null)
                {
                    // "1+2" の時点では入力中の "2"、
                    // "1+2+" の時点では計算結果の "3" を返します
                    value =
                        (getButtonTypeOf(_LastPushed) == ButtonType.Num)
                        ? _CurrValue : _Result;
                }
                else
                {
                    // スタックでの計算中は、常に入力中の値
                    value = _Stack._LastValue;
                }
                return value.ToString();
            }
        }
        /// 
        /// 計算結果
        /// 
        public decimal Result
        {
            get
            {
                // 計算の途中であれば "=" を押して終わらせる
                if (_LastPushed != ToyCalcButtons.Equal)
                    Push(ToyCalcButtons.Equal);
                return _ErrorReason == "" ? _Result : 0m;
            }
        }
        #region ボタンのタイプ
        private enum ButtonType { Clear, Num, Operator }
        [System.Diagnostics.DebuggerStepThrough]
        private ButtonType getButtonTypeOf(ToyCalcButtons button)
        {
            switch (button)
            {
                case ToyCalcButtons.Clear:
                case ToyCalcButtons.ClearEntry:
                    return ButtonType.Clear;
                case ToyCalcButtons.Zero:
                case ToyCalcButtons.One:
                case ToyCalcButtons.Two:
                case ToyCalcButtons.Three:
                case ToyCalcButtons.Four:
                case ToyCalcButtons.Five:
                case ToyCalcButtons.Six:
                case ToyCalcButtons.Seven:
                case ToyCalcButtons.Eight:
                case ToyCalcButtons.Nine:
                    return ButtonType.Num;
                case ToyCalcButtons.Add:
                case ToyCalcButtons.Subtract:
                case ToyCalcButtons.Multiply:
                case ToyCalcButtons.Divide:
                case ToyCalcButtons.Equal:
                    return ButtonType.Operator;
                default:
                    throw new ArgumentException("不明なボタン", "button");
            }
        }