计算器
界面
- 如果一些特殊的字符
×、÷、±
打印不出来,可以使用特殊的输入法,或者直接在这里Copy。 - 设置输入框(txtData)的字体
Font
属性。 - 输入框(txtData)设置为只读。
ReadOnly
设为true
。 - 输入框(txtData)设置为文本右对齐。
TextAlign
设为Right
。
清除输入与退格
C#中的事件触发机制。
选择CE按钮 - 打开属性面板 - 点击事件按钮 - 在Click事件中填写
btnCE_Click
,或者直接双击,添加事件处理函数。这个事件处理函数意味着,当点击CE按键时调用对应的
btnCE_Click
函数。面向对象的编程讲究:什么时候谁去做什么事。
const string EMPTY_TEXT = ""; private void btnCE_Click(object sender, EventArgs e) { // 面向对象的编程,要说明是谁(txtData)的属性和方法。 // 将txtData的文本(Text)设为 Hello World //txtData.Text = "Hello World"; // 清空文本 // 将txtData的文本(Text)设为空 txtData.Text = EMPTY_TEXT; }
private void btnBackspace_Click(object sender, EventArgs e) { // 去掉最后一位 if (txtData.Text.Length > 0) txtData.Text = txtData.Text.Substring(0, txtData.Text.Length - 1); }
数字
- 设置0~9这些数字以及小数点的点击事件处理函数都设为
Number_Click
。 - 通过
sender
参数可以区分点击的是哪个按钮。private void Number_Click(object sender, EventArgs e) { // 追加文字 txtData.Text = txtData.Text + ((Button)sender).Text; }
数字0
- 数字前的0应该要被忽略掉。
可以使用数据类型转化,验证输入是否合理。
private void Number_Click(object sender, EventArgs e) { // 追加文字 string txt = txtData.Text + ((Button)sender).Text; // 尝试将字符串转化为数字,以确认数据是合理的。 double data; if (Double.TryParse(txt, out data)) { txtData.Text = data.ToString(); } }
小数点
- 输入多个小数点也是不合理的。
我们这里没有考虑直接用小数点开头的数字。
private void Number_Click(object sender, EventArgs e) { // 追加文字 string txt = txtData.Text + ((Button)sender).Text; // 尝试将字符串转化为数字,以确认数据是合理的。 double data; if (Double.TryParse(txt, out data)) { txtData.Text = data.ToString(); // 如果点击的是小数点,就把小数点追加到输入框。 if (((Button)sender).Text == ".") txtData.Text += "."; } }
正负号
- 标记正负。负号总是显示在数字的最前面。
private void btnSign_Click(object sender, EventArgs e) { // 判断数据前是否有负号 if (txtData.Text.StartsWith("-")) { // 去掉负号 txtData.Text = txtData.Text.Substring(1); } else { // 加上负号 txtData.Text = "-" + txtData.Text; } }
运算
+
、-
、*
、/
都有两个运算数。所以要用两个变量来记录这两个运算数,还需要一个变量来记录运算符。根据两个运算数和一个运算符计算结果。
// 第一个操作数 double number1; // 运算符 string operate; // 运算,并将运算的结果保存到number1中,以便进一步运算。 private void Compute() { // 第一个操作数保存在number1中 // 运算符保存在operate中 // 第二个操作数显示在文本框中 // 能拿到这三个数据就可运算了 // 如果没有第二个操作数,就不运算了。 double number2; if (!Double.TryParse(txtData.Text, out number2)) return; // 运算,并将运算的结果保存到number1中,以便进一步运算。 switch (operate) { case "+": number1 = number1 + number2; break; case "-": number1 = number1 - number2; break; case "×": number1 = number1 * number2; break; case "÷": number1 = number1 / number2; break; default: number1 = number2; break; } }
运算符
输入运算符后,将之前的数据进行运算,结果存入第一个运算数,并清空输入框开始输入第二个运算数。
private void Operator_Click(object sender, EventArgs e) { // 将之前的数据进行运算,结果存入第一个运算数。 Compute(); // 记录操作符 operate = ((Button)sender).Text; // 显示计算历史 lblCompute.Text = number1 + " " + operate; // 清空输入框,方便输入第二个操作数。 txtData.Text = EMPTY_TEXT; }
求结果
- 输入
=
完成当前运算。 计算后可以清除当前运算符operate,防止再次运算。
private void btnCompute_Click(object sender, EventArgs e) { // 运算 Compute(); // 显示结果 txtData.Text = number1.ToString(); lblCompute.Text = txtData.Text; // 计算完了就清除operate,防止再次运算。 operate = null; }
清除
重置所有的变量和数据。
private void btnClear_Click(object sender, EventArgs e) { // 清空所有的显示数据 txtData.Text = EMPTY_TEXT; lblCompute.Text = null; // 还原所有的变量 number1 = 0; operate = null; }
测试
- 数字0,测试用例: 00012
- 输入小数,测试用例: 1..23、1.23.4
- 输入负数,测试用例:12---3-
- 常规运算,测试用例:1 + 2 =、 1 / 0 =
- 连续运算,测试用例:+、1 + 2 * 3
- 运算符切换, 测试用例:1 * + 2
- 多少输入运算符, 测试用例:3 * *