WPF学习笔记(27)科学计算器

发布于:2025-07-11 ⋅ 阅读:(16) ⋅ 点赞:(0)


1. 前端界面

<Window x:Class="CSDN_Cal.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:CSDN_Cal"
        mc:Ignorable="d"
        Title="科学计算器" Height="600" Width="400"
        WindowStartupLocation="CenterScreen"
        ResizeMode="NoResize">
    <Window.Resources>
        <Style TargetType="Button">
            <Setter Property="FontSize" Value="20"/>
            <Setter Property="Margin" Value="5"/>
            <Setter Property="Background" Value="#FF333333"/>
            <Setter Property="Foreground" Value="White"/>
            <Setter Property="BorderThickness" Value="0"/>
            <Setter Property="BorderBrush" Value="#FF555555"/>
        </Style>
    </Window.Resources>

    <Grid Background="#FF222222">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>

        <!-- 显示区域 -->
        <Border Grid.Row="0" Background="#FF111111" Padding="10,10,10,10" Margin="10,10,10,10">
            <StackPanel>
                <TextBlock x:Name="txtHistory" Foreground="#FFAAAAAA" FontSize="16" 
                           HorizontalAlignment="Right" Margin="0,0,0,5"/>
                <TextBlock x:Name="txtDisplay" Foreground="White" FontSize="36" 
                           HorizontalAlignment="Right" Text="0"/>
            </StackPanel>
        </Border>

        <!-- 按钮区域 -->
        <Grid Grid.Row="1" Margin="10">
            <Grid.RowDefinitions>
                <RowDefinition Height="*"/>
                <RowDefinition Height="*"/>
                <RowDefinition Height="*"/>
                <RowDefinition Height="*"/>
                <RowDefinition Height="*"/>
                <RowDefinition Height="*"/>
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="*"/>
                <ColumnDefinition Width="*"/>
                <ColumnDefinition Width="*"/>
                <ColumnDefinition Width="*"/>
                <ColumnDefinition Width="*"/>
            </Grid.ColumnDefinitions>

            <!-- 第二行 -->
            <Button x:Name="btnClear" Grid.Row="1" Grid.Column="0" Content="C" Background="#FFAA0000"/>
            <Button x:Name="btnBack" Grid.Row="1" Grid.Column="1" Content=""/>
            <Button x:Name="btnPercent" Grid.Row="1" Grid.Column="2" Content="%"/>
            <Button x:Name="btnDivide" Grid.Row="1" Grid.Column="3" Content="/" Background="#FF555555"/>
            <Button x:Name="btnSqrt" Grid.Row="1" Grid.Column="4" Content="" Background="#FF555555"/>
            
            <!-- 第一行 -->
            <Button x:Name="btnTan" Grid.Row="0" Grid.Column="0" Content="tan" Background="#FF555555"/>
            <Button x:Name="btnLog" Grid.Row="0" Grid.Column="1" Content="log" Background="#FF555555"/>
            <Button x:Name="btnLn" Grid.Row="0" Grid.Column="2" Content="ln" Background="#FF555555"/>
            <Button x:Name="btnPi" Grid.Row="0" Grid.Column="3" Content="π" Background="#FF555555"/>
            <Button x:Name="btnFactorial" Grid.Row="0" Grid.Column="4" Content="n!" Background="#FF555555"/>
            <!-- 第三行 -->
            <Button x:Name="btn7" Grid.Row="2" Grid.Column="0" Content="7" />
            <Button x:Name="btn8" Grid.Row="2" Grid.Column="1" Content="8"/>
            <Button x:Name="btn9" Grid.Row="2" Grid.Column="2" Content="9"/>
            <Button x:Name="btnMultiply" Grid.Row="2" Grid.Column="3" Content="×" Background="#FF555555"/>
            <Button x:Name="btnPower" Grid.Row="2" Grid.Column="4" Content="x^y" Background="#FF555555"/>

            <!-- 第四行 -->
            <Button x:Name="btn4" Grid.Row="3" Grid.Column="0" Content="4"/>
            <Button x:Name="btn5" Grid.Row="3" Grid.Column="1" Content="5"/>
            <Button x:Name="btn6" Grid.Row="3" Grid.Column="2" Content="6"/>
            <Button x:Name="btnSubtract" Grid.Row="3" Grid.Column="3" Content="-" Background="#FF555555"/>
            <Button x:Name="btnSin" Grid.Row="3" Grid.Column="4" Content="sin" Background="#FF555555"/>

            <!-- 第五行 -->
            <Button x:Name="btn1" Grid.Row="4" Grid.Column="0" Content="1"/>
            <Button x:Name="btn2" Grid.Row="4" Grid.Column="1" Content="2"/>
            <Button x:Name="btn3" Grid.Row="4" Grid.Column="2" Content="3"/>
            <Button x:Name="btnAdd" Grid.Row="4" Grid.Column="3" Content="+" Background="#FF555555"/>
            <Button x:Name="btnCos" Grid.Row="4" Grid.Column="4" Content="cos" Background="#FF555555"/>

            <!-- 第六行 -->
            <Button x:Name="btn0" Grid.Row="5" Grid.Column="0" Content="0"/>
            <Button x:Name="btnDecimal" Grid.Row="5" Grid.Column="1" Content="."/>
            <Button x:Name="btnPlusMinus" Grid.Row="5" Grid.Column="2" Content="±"/>
            <Button x:Name="btnEquals" Grid.Row="5" Grid.Column="3" Grid.ColumnSpan="2" Content="=" Background="#FF007ACC"/>
        </Grid>
    </Grid>
</Window>

2. 功能代码

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;

namespace CSDN_Cal
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        private string currentInput = "0";//当前输入
        private string previousInput = "";//之前输入
        private string operation = "";//操作符
        private bool newInput = true;
        private bool operationPerformed = false;//操作已执行

        public MainWindow()
        {
            InitializeComponent();

            // 数字按钮事件
            btn0.Click += NumberButton_Click;
            btn1.Click += NumberButton_Click;
            btn2.Click += NumberButton_Click;
            btn3.Click += NumberButton_Click;
            btn4.Click += NumberButton_Click;
            btn5.Click += NumberButton_Click;
            btn6.Click += NumberButton_Click;
            btn7.Click += NumberButton_Click;
            btn8.Click += NumberButton_Click;
            btn9.Click += NumberButton_Click;

            // 运算符按钮事件
            btnAdd.Click += OperatorButton_Click;
            btnSubtract.Click += OperatorButton_Click;
            btnMultiply.Click += OperatorButton_Click;
            btnDivide.Click += OperatorButton_Click;
            btnEquals.Click += EqualsButton_Click;

            // 功能按钮事件
            btnClear.Click += ClearButton_Click;
            btnBack.Click += BackButton_Click;
            btnDecimal.Click += DecimalButton_Click;
            btnPlusMinus.Click += PlusMinusButton_Click;
            btnPercent.Click += PercentButton_Click;

            // 科学计算按钮事件
            btnSqrt.Click += ScientificButton_Click;
            btnPower.Click += ScientificButton_Click;
            btnSin.Click += ScientificButton_Click;
            btnCos.Click += ScientificButton_Click;
            btnTan.Click += ScientificButton_Click;
            btnLog.Click += ScientificButton_Click;
            btnLn.Click += ScientificButton_Click;
            btnPi.Click += ScientificButton_Click;
            btnFactorial.Click += ScientificButton_Click;
        }

        private void NumberButton_Click(object sender, RoutedEventArgs e)
        {
            Button button = (Button)sender;

            if (currentInput == "0" || newInput)
            {
                currentInput = button.Content.ToString();
                newInput = false;
            }
            else
            {
                currentInput += button.Content.ToString();
            }

            UpdateDisplay();
        }

        private void OperatorButton_Click(object sender, RoutedEventArgs e)
        {
            Button button = (Button)sender;

            if (!newInput && !operationPerformed)
            {
                Calculate();
            }

            operation = button.Content.ToString();
            previousInput = currentInput;
            newInput = true;
            operationPerformed = false;

            UpdateHistory();
        }

        private void EqualsButton_Click(object sender, RoutedEventArgs e)
        {
            Calculate();
            operation = "";
            UpdateHistory();
            newInput = true;
            operationPerformed = true;
        }

        private void Calculate()
        {
            if (string.IsNullOrEmpty(previousInput) || string.IsNullOrEmpty(operation))
                return;

            double num1 = double.Parse(previousInput);
            double num2 = double.Parse(currentInput);
            double result = 0;

            switch (operation)
            {
                case "+":
                    result = num1 + num2;
                    break;
                case "-":
                    result = num1 - num2;
                    break;
                case "×":
                    result = num1 * num2;
                    break;
                case "/":
                    result = num1 / num2;
                    break;
            }

            currentInput = result.ToString();
            UpdateDisplay();
        }

        private void ScientificButton_Click(object sender, RoutedEventArgs e)
        {
            Button button = (Button)sender;
            double num = double.Parse(currentInput);
            double result = 0;

            switch (button.Content.ToString())
            {
                case "√":
                    result = Math.Sqrt(num);
                    break;
                case "x^y":
                    // 需要额外处理幂运算
                    previousInput = currentInput;
                    operation = "^";
                    newInput = true;
                    UpdateHistory();
                    return;
                case "sin":
                    result = Math.Sin(num * Math.PI / 180); // 转换为弧度
                    break;
                case "cos":
                    result = Math.Cos(num * Math.PI / 180);
                    break;
                case "tan":
                    result = Math.Tan(num * Math.PI / 180);
                    break;
                case "log":
                    result = Math.Log10(num);
                    break;
                case "ln":
                    result = Math.Log(num);
                    break;
                case "π":
                    currentInput = Math.PI.ToString();
                    UpdateDisplay();
                    return;
                case "n!":
                    result = Factorial((int)num);
                    break;
            }

            currentInput = result.ToString();
            UpdateDisplay();
            newInput = true;
        }

        private int Factorial(int n)
        {
            if (n <= 1)
                return 1;
            return n * Factorial(n - 1);
        }

        private void ClearButton_Click(object sender, RoutedEventArgs e)
        {
            currentInput = "0";
            previousInput = "";
            operation = "";
            newInput = true;
            UpdateDisplay();
            txtHistory.Text = "";
        }

        private void BackButton_Click(object sender, RoutedEventArgs e)
        {
            if (currentInput.Length > 1)
            {
                currentInput = currentInput.Substring(0, currentInput.Length - 1);
            }
            else
            {
                currentInput = "0";
                newInput = true;
            }

            UpdateDisplay();
        }

        private void DecimalButton_Click(object sender, RoutedEventArgs e)
        {
            if (!currentInput.Contains("."))
            {
                currentInput += ".";
                UpdateDisplay();
            }
        }

        private void PlusMinusButton_Click(object sender, RoutedEventArgs e)
        {
            if (currentInput != "0")
            {
                if (currentInput.StartsWith("-"))
                {
                    currentInput = currentInput.Substring(1);
                }
                else
                {
                    currentInput = "-" + currentInput;
                }

                UpdateDisplay();
            }
        }

        private void PercentButton_Click(object sender, RoutedEventArgs e)
        {
            double num = double.Parse(currentInput);
            currentInput = (num / 100).ToString();
            UpdateDisplay();
        }

        private void UpdateDisplay()
        {
            txtDisplay.Text = currentInput;
        }

        private void UpdateHistory()
        {
            //$为字符串拼接的优化,等同于string.Format(),示例如下:
            txtHistory.Text = $"{previousInput} {operation}";
        }
    }
}

网站公告

今日签到

点亮在社区的每一天
去签到