WPF计算器多运算符连续使用异常问题求助
WPF计算器多运算符处理问题
我的WPF计算器还没做完,核心卡在运算符处理上:所有运算符共用同一个处理逻辑,只能支持单次运算,第二次按运算符会直接覆盖前一个;哪怕输入包含两个及以上运算符的表达式,最终计算也只会用最后一个运算符。
忽略x²和sqrt(这两个运算符,下面是相关代码:
public partial class MainWindow : Window { string Input = " "; string Operator = null; public MainWindow() { InitializeComponent(); this.SizeToContent = SizeToContent.Width; this.SizeToContent = SizeToContent.Height; } private void Number_Click(object sender, RoutedEventArgs e) { string Input = " "; Button button = (Button)sender; Input += button.Content.ToString(); Equation.Text += button.Content.ToString(); } private void Operator_Click(object sender, RoutedEventArgs e) { Button button = (Button)sender; if (!string.IsNullOrEmpty(Operator)) { Operator += button.Content.ToString(); Input = " "; } Operator = button.Content.ToString(); Equation.Text += button.Content.ToString(); } private void b_equal_Click(object sender, RoutedEventArgs e) { Equation.Text = Calculon(Operator); } private string Calculon(string Operator) { double Result = 0; string Error = "Syntaxfehler"; string[] Text = Equation.Text.Split(" "); for (int i = 0; i < Text.Length - 2;) { double numberOne = Convert.ToDouble(Text[i]); double numberTwo = Convert.ToDouble(Text[i + 2]); if (Operator == " x ") { Result = numberOne * numberTwo; } if (Operator == " - ") { Result = numberOne - numberTwo; } if (Operator == " + ") { Result = numberOne + numberTwo; } if (Operator == " / ") { Result = numberOne / numberTwo; } if (Operator == " ² ") { Result = Math.Round(numberOne,2); } if (Operator == " sqrt( ") { Result = Math.Sqrt(numberOne); } i += 2; Text[i] = Result.ToString(); } if (Result.Equals(double.NaN)) { return Error; } return Result.ToString(); } private void b_Clear_Click(object sender, RoutedEventArgs e) { Equation.Text = null; } private void bpunkt_Click(object sender, RoutedEventArgs e) { Equation.Text += ","; } }
我试过定义两个Operator变量,但只在两个运算符的场景下有效,超过两个就又出现问题;也想过用循环处理,但因为按下运算符时输入的表达式还没完成,不知道该怎么实现,求帮忙解决。
问题分析
你的代码存在几个核心问题:
- 变量作用域错误:
Number_Click里重新定义了局部Input,导致全局Input完全没用,输入的数字没被正确记录 - 运算符存储逻辑矛盾:全局
Operator是单个字符串,每次点击都会直接覆盖前值;且Operator_Click里先拼接再覆盖的逻辑完全无效,没法存储多运算符 - 计算逻辑偏差:
Calculon只接收最后一个运算符,用它处理所有运算步骤,完全忽略表达式里的实际运算符顺序
修复方案
改用列表存储数字和运算符的方式,把每一步的操作都记录下来,支持多运算符连续计算。
修改后的完整代码
public partial class MainWindow : Window { // 存储输入的数字与对应运算符 private List<double> _numbers = new List<double>(); private List<string> _operators = new List<string>(); private string _currentInput = ""; public MainWindow() { InitializeComponent(); SizeToContent = SizeToContent.WidthAndHeight; } private void Number_Click(object sender, RoutedEventArgs e) { Button button = (Button)sender; _currentInput += button.Content.ToString(); Equation.Text += button.Content.ToString(); } private void Operator_Click(object sender, RoutedEventArgs e) { Button button = (Button)sender; string op = button.Content.ToString(); // 先存储当前输入的数字 if (!string.IsNullOrEmpty(_currentInput)) { if (double.TryParse(_currentInput, out double num)) { _numbers.Add(num); _currentInput = ""; } else { Equation.Text = "输入错误"; ClearAll(); return; } } // 存储当前运算符 _operators.Add(op); Equation.Text += op; } private void b_equal_Click(object sender, RoutedEventArgs e) { // 存储最后一个输入的数字 if (!string.IsNullOrEmpty(_currentInput)) { if (double.TryParse(_currentInput, out double num)) { _numbers.Add(num); _currentInput = ""; } else { Equation.Text = "输入错误"; ClearAll(); return; } } // 检查数字与运算符数量是否匹配 if (_numbers.Count != _operators.Count + 1) { Equation.Text = "语法错误"; ClearAll(); return; } // 按顺序执行计算 double result = _numbers[0]; for (int i = 0; i < _operators.Count; i++) { string op = _operators[i]; double nextNum = _numbers[i + 1]; switch (op) { case " + ": result += nextNum; break; case " - ": result -= nextNum; break; case " x ": result *= nextNum; break; case " / ": if (nextNum == 0) { Equation.Text = "除以零错误"; ClearAll(); return; } result /= nextNum; break; // 忽略x²和sqrt(,暂不处理 } } Equation.Text = result.ToString(); // 将结果作为下一次计算的初始值 ClearAll(); _currentInput = result.ToString(); } private void b_Clear_Click(object sender, RoutedEventArgs e) { ClearAll(); Equation.Text = ""; } private void bpunkt_Click(object sender, RoutedEventArgs e) { // 避免重复输入小数点 if (!_currentInput.Contains(",")) { _currentInput += ","; Equation.Text += ","; } } // 清空所有存储数据 private void ClearAll() { _numbers.Clear(); _operators.Clear(); _currentInput = ""; } }
关键修改说明
- 存储结构优化:用
_numbers和_operators列表分别记录输入的数字与运算符,完美支持多步骤运算 - 输入逻辑修复:移除局部变量覆盖问题,增加小数点重复输入判断,提升输入合法性
- 运算符处理修正:每次点击运算符时先存储当前输入的数字,再记录运算符,确保每一步操作都被保存
- 计算逻辑重构:按输入顺序遍历运算符列表,依次处理相邻数字;增加错误判断(语法错误、除以零)
- 交互体验优化:计算完成后将结果作为下一次计算的初始值,符合普通计算器使用习惯
内容的提问来源于stack exchange,提问作者Laszlo Adams
相关产品推荐
相关产品推荐

