C#——簡單的計算器(仿Windows 10計算器)

問題描述

運用WPF技術,模仿Windows 10系統中計算機器(Calculator)程序,開發一個類似程序。

問題分析

注: 

  • MS:記憶當前顯示的數字(Memory Save)
  • MC:清除記憶的數字(Memory Clean)
  • MR:顯示記憶的數字(Memory Recall)
  • M-:記憶的數字減去當前數字,並保存
  • M+:記憶的數字加上當前數字,並保存

解決方案 

創建WPF應用

 

UI設計

 Metro風格來美化:https://www.cnblogs.com/ouyangkai/p/12759466.html

App.xaml 

<Application x:Class="Homework19.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:Homework19"
             StartupUri="MainWindow.xaml">
    <Application.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <!-- MahApps.Metro resource dictionaries. Make sure that all file names are Case Sensitive! -->
                <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Controls.xaml" />
                <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Fonts.xaml" />
                <!-- Accent and AppTheme setting -->
                <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Themes/Light.Blue.xaml" />
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Application.Resources>
</Application>

 MainWindow.xaml

<Controls:MetroWindow x:Class="Homework19.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:Homework19"
        xmlns:Controls="clr-namespace:MahApps.Metro.Controls;assembly=MahApps.Metro"
        mc:Ignorable="d"
        ResizeMode = "NoResize"
        Title="計算器" Height="750" Width="1000">
    <Grid>
        <TextBlock x:Name="Out_2" HorizontalAlignment="Left" Margin="10,55,0,0" TextWrapping="Wrap" 
                   VerticalAlignment="Top" Height="33" Width="670" TextAlignment="Right" FontSize="24">
            <Run/>
                <LineBreak/>
            <Run/>
        </TextBlock>
        <TextBlock x:Name="Out_1" HorizontalAlignment="Left" Margin="10,93,0,0" TextWrapping="Wrap" Text="0" 
                   VerticalAlignment="Top" Height="91" Width="670" TextAlignment="Right" FontSize="72" 
                   FontFamily="Microsoft YaHei"/>
        <Button x:Name="btnMenu" Content="≡標準" HorizontalAlignment="Left" Margin="10,10,0,0" 
                VerticalAlignment="Top" Width="70" Height="40" FontSize="20" Click="Button_Click">
            <Button.ContextMenu>
                <ContextMenu Name="contextMenu">
                    <MenuItem Header="標準"/>
                    <MenuItem Header="科學"/>
                    <MenuItem Header="程序員"/>
                    <MenuItem Header="日期計算"/>
                </ContextMenu>
            </Button.ContextMenu>
        </Button>
        <Button x:Name="B_MC" Content="MC" HorizontalAlignment="Left" Margin="10,189,0,0" VerticalAlignment="Top" 
                Width="70" Height="40" Click="B_MC_Click"/>
        <Button x:Name="B_MR" Content="MR" HorizontalAlignment="Left" Margin="85,189,0,0" VerticalAlignment="Top" 
                Width="70" Height="40" Click="B_MR_Click"/>
        <Button x:Name="B_M__1" Content="M+" HorizontalAlignment="Left" Margin="160,189,0,0" VerticalAlignment="Top" 
                Width="70" Height="40" Click="B_M__1_Click"/>
        <Button x:Name="B_M__" Content="M-" HorizontalAlignment="Left" Margin="235,189,0,0" VerticalAlignment="Top" 
                Width="70" Height="40" Click="B_M___Click"/>
        <Button x:Name="B_MS" Content="MS" HorizontalAlignment="Left" Margin="310,189,0,0" VerticalAlignment="Top" 
                Width="70" Height="40" Click="B_MS_Click"/>
        <Button x:Name="B_per" Content="%" HorizontalAlignment="Left" Margin="10,236,0,0" VerticalAlignment="Top" 
                Width="130" Height="90" FontSize="24" FontFamily="Microsoft YaHei UI Light" Click="B_per_Click"/>
        <Button x:Name="B_CE" Content="CE" HorizontalAlignment="Left" Margin="145,236,0,0" VerticalAlignment="Top" 
                Width="130" Height="90" FontSize="24" FontFamily="Microsoft YaHei UI Light" Click="B_CE_Click"/>
        <Button x:Name="B_C" Content="C" HorizontalAlignment="Left" Margin="280,236,0,0" VerticalAlignment="Top" 
                Width="130" Height="90" FontSize="24" FontFamily="Microsoft YaHei UI Light" Click="B_C_Click"/>
        <Button x:Name="B_delete" Content="&lt;-" HorizontalAlignment="Left" Margin="415,236,0,0" VerticalAlignment="Top" 
                Width="130" Height="90" FontSize="24" FontFamily="Microsoft YaHei UI Light" Click="B_delete_Click"/>
        <Button Content="÷" HorizontalAlignment="Left" Margin="550,236,0,0" VerticalAlignment="Top" 
                Width="130" Height="90" FontSize="48" FontFamily="Microsoft YaHei UI Light" Click="operater_Button_Click"/>
        <Button x:Name="B_radical" Content="√" HorizontalAlignment="Left" Margin="10,331,0,0" VerticalAlignment="Top" 
                Width="130" Height="90" FontSize="36" FontFamily="Microsoft YaHei UI Light" Click="B_radical_Click"/>
        <Button x:Name="B_7" Content="7" HorizontalAlignment="Left" Margin="145,331,0,0" VerticalAlignment="Top" 
                Width="130" Height="90" FontSize="36" Click="B_NUM_Click"/>
        <Button x:Name="B_8" Content="8" HorizontalAlignment="Left" Margin="280,331,0,0" VerticalAlignment="Top" 
                Width="130" Height="90" FontSize="36" Click="B_NUM_Click"/>
        <Button x:Name="B_9" Content="9" HorizontalAlignment="Left" Margin="415,331,0,0" VerticalAlignment="Top" 
                Width="130" Height="90" FontSize="36" Click="B_NUM_Click"/>
        <Button Content="×" HorizontalAlignment="Left" Margin="550,331,0,0" VerticalAlignment="Top" 
                Width="130" Height="90" FontSize="48" FontFamily="Microsoft YaHei UI Light" Click="operater_Button_Click"/>
        <Button x:Name="B_sq" Content="x²" HorizontalAlignment="Left" Margin="10,426,0,0" VerticalAlignment="Top" 
                Width="130" Height="90" FontSize="36" FontFamily="Microsoft YaHei UI Light" Click="B_sq_Click"/>
        <Button x:Name="B_4" Content="4" HorizontalAlignment="Left" Margin="145,426,0,0" VerticalAlignment="Top" 
                Width="130" Height="90" FontSize="36" Click="B_NUM_Click"/>
        <Button x:Name="B_5" Content="5" HorizontalAlignment="Left" Margin="280,426,0,0" VerticalAlignment="Top" 
                Width="130" Height="90" FontSize="36" Click="B_NUM_Click"/>
        <Button x:Name="B_6" Content="6" HorizontalAlignment="Left" Margin="415,426,0,0" VerticalAlignment="Top" 
                Width="130" Height="90" FontSize="36" Click="B_NUM_Click"/>
        <Button x:Name="B_sub" Content="-" HorizontalAlignment="Left" Margin="550,426,0,0" VerticalAlignment="Top" 
                Width="130" Height="90" FontSize="48" FontFamily="Microsoft YaHei UI Light" Click="operater_Button_Click"/>
        <Button x:Name="B_cu" Content="x³" HorizontalAlignment="Left" Margin="10,521,0,0" VerticalAlignment="Top" 
                Width="130" Height="90" FontSize="36" FontFamily="Microsoft YaHei UI Light" Click="B_cu_Click"/>
        <Button x:Name="B_1" Content="1" HorizontalAlignment="Left" Margin="145,521,0,0" VerticalAlignment="Top" 
                Width="130" Height="90" FontSize="36" Click="B_NUM_Click"/>
        <Button x:Name="B_2" Content="2" HorizontalAlignment="Left" Margin="280,521,0,0" VerticalAlignment="Top" 
                Width="130" Height="90" FontSize="36" Click="B_NUM_Click"/>
        <Button x:Name="B_3" Content="3" HorizontalAlignment="Left" Margin="415,521,0,0" VerticalAlignment="Top" 
                Width="130" Height="90" FontSize="36" Click="B_NUM_Click"/>
        <Button Content="+" HorizontalAlignment="Left" Margin="550,521,0,0" VerticalAlignment="Top" 
                Width="130" Height="90" FontSize="48" FontFamily="Microsoft YaHei UI Light" Click="operater_Button_Click"/>
        <Button x:Name="B_reciprocal" Content="1/x" HorizontalAlignment="Left" Margin="10,616,0,0" VerticalAlignment="Top" 
                Width="130" Height="90" FontSize="24" FontFamily="Microsoft YaHei UI Light" Click="B_reciprocal_Click"/>
        <Button x:Name="B_opp" Content="±" HorizontalAlignment="Left" Margin="145,616,0,0" VerticalAlignment="Top" 
                Width="130" Height="90" FontSize="36" FontFamily="Microsoft YaHei UI Light" Click="B_opp_Click"/>
        <Button x:Name="B_0" Content="0" HorizontalAlignment="Left" Margin="280,616,0,0" VerticalAlignment="Top" 
                Width="130" Height="90" FontSize="36" Click="B_NUM_Click"/>
        <Button Content="." HorizontalAlignment="Left" Margin="415,616,0,0" VerticalAlignment="Top" 
                Width="130" Height="90" FontSize="36" FontFamily="Microsoft YaHei UI Light" Click="Button_Click_1"/>
        <Button x:Name="B_eq" Content="=" HorizontalAlignment="Left" Margin="550,616,0,0" VerticalAlignment="Top" 
                Width="130" Height="90" FontSize="36" FontFamily="Microsoft YaHei UI Light" Click="B_eq_Click"/>
        <TabControl Margin="700,0,0,0">
            <TabItem>
                <TabItem.Header >
                    歷史記錄
                </TabItem.Header>
                <Grid>
                    <ScrollViewer HorizontalScrollBarVisibility="Auto" Margin="0,0,0,25">
                        <StackPanel x:Name="historyPanel" >

                        </StackPanel>
                    </ScrollViewer>
                    <Button x:Name="clear_Btn" Height="8" Margin="0,650,0,0" Click="clear_Btn_Click">
                        全部清空
                    </Button>
                </Grid>
            </TabItem>
            <TabItem Header="內存">
                <!--Bind TextBlock.Text to the TextBox on the first TabItem.-->
                <TextBlock Text="{Binding ElementName=textBox1, Path=Text}"/>
            </TabItem>
        </TabControl>

        <!--
        <Grid>
        -->
            <!-- Declare normal view content here -->
        <!--
            <Border CornerRadius="5" Background="White" BorderBrush="LightGray" 
                    BorderThickness="1" Width="200" Height="100" Panel.ZIndex="10">
                <Border.Effect>
                    <DropShadowEffect BlurRadius="10" Direction="270" ShadowDepth="7" Opacity="0.5"/>
                </Border.Effect>
                <TextBlock Text="I'm a fake Popup control" HorizontalAlignment="Center" VerticalAlignment="Center"/>
            </Border>
        </Grid> -->
    </Grid>
</Controls:MetroWindow>

邏輯設計 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using MahApps.Metro.Controls;
using System.Windows.Controls.Primitives;

namespace Homework19
{
    /// <summary>
    /// MainWindow.xaml 的交互邏輯
    /// </summary>
    public partial class MainWindow : MetroWindow
    {
        public MainWindow()
        {
            InitializeComponent();
            B_MC.IsEnabled = false;
            B_M__1.IsEnabled = false;
            B_M__.IsEnabled = false;
            B_MR.IsEnabled = false;
            
        }

        //temp用於臨時存儲操作數,oper存儲最近一次的運算符
        private double temp, op1, op2, memory, result;
        private string history=null,oper = null;
        //next用來表示是否要輸入新的操作數
        private bool next;

        //連續計算時先計算前面的結果
        private void Aut()
        {
            op2 = Convert.ToDouble(Out_1.Text);
            switch (oper)
            {
                case "+":
                    result = op1 + op2;
                    break;
                case "-":
                    result = op1 - op2;
                    break;
                case "×":
                    result = op1 * op2;
                    break;
                case "÷":
                    result = op1 / op2;
                    break;
                default:
                    break;

            }
            Out_1.Text = Convert.ToString(result);
            //Out_2.Text = Convert.ToString(result);
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            //目標
            this.contextMenu.PlacementTarget = this.btnMenu;
            //位置
            this.contextMenu.Placement = PlacementMode.Top;
            //顯示菜單
            this.contextMenu.IsOpen = true;
        }
        private void B_NUM_Click(object sender, RoutedEventArgs e)
        {
            Button numBtn = sender as Button;
            string numstr = numBtn.Content.ToString();
            if (numstr != "0")
            {
                if (Out_1.Text == "0" || next)
                {
                    Out_1.Text = numstr;
                    if (next)
                    {
                        next = false;
                    }
                }
                else
                    Out_1.Text += numstr;
            }
            else {
                if (Out_1.Text != "0")
                {
                    Out_1.Text += "0";
                }
                if (next)
                {
                    Out_1.Text = "0";
                    next = false;
                }
            }
        }

        private void B_C_Click(object sender, RoutedEventArgs e)
        {
            Out_1.Text = "0";
            Out_2.Text = "";
            oper = null;
        }

        private void B_CE_Click(object sender, RoutedEventArgs e)
        {
            Out_1.Text = "0";
            Out_2.Text = "";
            oper = null;
        }
        
        private void operater_Button_Click(object sender, RoutedEventArgs e)
        {
            Button operaterBtn = sender as Button;
            string operater = operaterBtn.Content.ToString();
            Out_2.Text += Out_1.Text + operater;
            if (oper != null)
            {
                Aut();
            }
            op1 = Convert.ToDouble(Out_1.Text);
            oper = operater;
            next = true;
        }

        private void B_delete_Click(object sender, RoutedEventArgs e)
        {
            if (!next)
            {
                if (Out_1.Text.Length == 1)
                {
                    Out_1.Text = "0";
                }
                else
                {
                    Out_1.Text = Out_1.Text.Substring(0, Out_1.Text.Length - 1);
                }
            }
        }

        private void B_reciprocal_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                temp = Convert.ToDouble(Out_1.Text);
                temp = 1 / temp;
                Out_1.Text = Convert.ToString(temp);
            }
            catch (Exception ee)
            {
                Out_1.Text = "除數不能爲0";
            }
        }

        private void B_sq_Click(object sender, RoutedEventArgs e)
        {
            temp = Convert.ToDouble(Out_1.Text);
            temp = Math.Pow(temp, 2);
            Out_1.Text = Convert.ToString(temp);
        }

        private void B_cu_Click(object sender, RoutedEventArgs e)
        {
            temp = Convert.ToDouble(Out_1.Text);
            temp = Math.Pow(temp, 3);
            Out_1.Text = Convert.ToString(temp);
        }

        private void B_radical_Click(object sender, RoutedEventArgs e)
        {
            temp = Convert.ToDouble(Out_1.Text);
            temp = Math.Pow(temp, 0.5);
            Out_1.Text = Convert.ToString(temp);
        }

        private void B_per_Click(object sender, RoutedEventArgs e)
        {
            temp = Convert.ToDouble(Out_1.Text);
            temp = temp / 100;
            Out_1.Text = Convert.ToString(temp);
        }

        private void B_MR_Click(object sender, RoutedEventArgs e)
        {
            Out_1.Text = Convert.ToString(memory);
        }

        private void B_M__1_Click(object sender, RoutedEventArgs e)
        {
            memory += Convert.ToDouble(Out_1.Text);
        }

        private void B_M___Click(object sender, RoutedEventArgs e)
        {
            memory -= Convert.ToDouble(Out_1.Text);
        }

        private void B_MC_Click(object sender, RoutedEventArgs e)
        {
            memory = 0;
            B_MC.IsEnabled = false;
            B_M__1.IsEnabled = false;
            B_M__.IsEnabled = false;
            B_MR.IsEnabled = false;
        }

        private void B_MS_Click(object sender, RoutedEventArgs e)
        {
            memory = Convert.ToDouble(Out_1.Text);
            B_MC.IsEnabled = true;
            B_M__1.IsEnabled = true;
            B_M__.IsEnabled = true;
            B_MR.IsEnabled = true;
        }

        private void clear_Btn_Click(object sender, RoutedEventArgs e)
        {
            historyPanel.Children.Clear();
        }

        private void B_eq_Click(object sender, RoutedEventArgs e)
        {
            op2 = Convert.ToDouble(Out_1.Text);
            switch (oper)
            {
                case "+":
                    result = op1 + op2;
                    break;
                case "-":
                    result = op1 - op2;
                    break;
                case "×":
                    result = op1 * op2;
                    break;
                case "÷":
                    result = op1 / op2;
                    break;
                default:
                    break;

            }
            oper = null;
            history = Out_2.Text + Out_1.Text + "=";
            Out_1.Text = Convert.ToString(result);
            Out_2.Text = "";
            Add_History(history, Convert.ToString(result));
        }

        private void B_opp_Click(object sender, RoutedEventArgs e)
        {
            temp = Convert.ToDouble(Out_1.Text);
            if (temp != 0)
            {
                temp = 0 - temp;
            }
            Out_1.Text = Convert.ToString(temp);
        }

        private void Button_Click_1(object sender, RoutedEventArgs e)
        {
            Out_1.Text += ".";
        }

        private void Add_History(string cal, string result){
            Border border = new Border();
            border.CornerRadius = new CornerRadius(5);
            border.Background = new SolidColorBrush(Colors.White);
            border.BorderBrush = new SolidColorBrush(Colors.LightGray);
            border.BorderThickness = new Thickness(1);
            border.Height = 100;
            Grid gird = new Grid();
            TextBlock textBlock1 = new TextBlock();
            textBlock1.HorizontalAlignment = HorizontalAlignment.Left; 
            textBlock1.Margin = new Thickness(10, 10, 0, 0); 
            textBlock1.TextWrapping = TextWrapping.Wrap;
            textBlock1.Text = cal;
            textBlock1.VerticalAlignment = VerticalAlignment .Top;
            textBlock1.Width = 260;
            textBlock1.Height = 28;
            textBlock1.TextAlignment = TextAlignment.Right;
            textBlock1.FontSize = 24;
            TextBlock textBlock2 = new TextBlock();
            textBlock2.HorizontalAlignment = HorizontalAlignment.Left;
            textBlock2.Margin = new Thickness(10, 30, 0, 0);
            textBlock2.TextWrapping = TextWrapping.Wrap;
            textBlock2.Text = result;
            textBlock2.VerticalAlignment = VerticalAlignment.Top;
            textBlock2.Width = 260;
            textBlock2.Height = 64;
            textBlock2.TextAlignment = TextAlignment.Right;
            textBlock2.FontSize = 54;
            textBlock2.FontFamily = new FontFamily("Microsoft YaHei");
            gird.Children.Add(textBlock1);
            gird.Children.Add(textBlock2);
            border.Child = gird;
            historyPanel.Children.Add(border);
        }
    }
}

運行結果

 

參考項目

Windows 10 計算器 C++源代碼 

https://github.com/Microsoft/calculator

仿Windows 10 計算器 C#源代碼 

https://github.com/BuXianShan/Calculator

參考文章

https://blog.csdn.net/weixin_43272781/article/details/106750837

https://blog.csdn.net/qq_43479622/article/details/91599602

https://blog.csdn.net/OneWord233/article/details/80755284

https://www.cnblogs.com/lonelyxmas/p/12117453.html

https://blog.csdn.net/weixin_42009898/article/details/80921151

https://www.cnblogs.com/ouyangkai/p/12759466.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章