C#编写的计算器程序(仿windows自带的计算器)

来源:互联网 发布:少儿编程前景 编辑:程序博客网 时间:2024/05/20 16:34

C#初学者,水平肯定是比较差的,欢迎大家批评指正!(开发环境visual studio2010,源代码下载地址:http://pan.baidu.com/s/1skOZGhZ)

废话不多数,上图上代码!微笑

(一)界面设计

“科学型”模式界面如下:


只实现了“标准型”和“科学型”两种模式。

切换到“标准型”时效果如下:


设计时,对于如何实现模式切换时界面的变化花了点功夫,最后是通过动态修改窗体大小和界面中控件的位置实现的。代码如下:

 private void ShowAsStandard()//“标准型”模式
        {
            groupT.Location = new Point(6, 78);//groupT中存放标准型模式下的按钮控件
            txtEnterBox.Size = new Size(250, 23);
            txtExpression.Size = new Size(250, 14);
            groupShowWindow.Size = new Size(260, 49);
            groupS.Location = new Point(-333, 77);//groupT中存放科学型模式下特有的按钮控件
            this.Size = new Size(290, 349);
        }
        private void ShowAsScience()//“科学型”模式
        {
            groupT.Location = new Point(268, 78);
            txtEnterBox.Size = new Size(511, 23);
            txtExpression.Size = new Size(511, 14);
            groupShowWindow.Size = new Size(517, 49);
            groupS.Location = new Point(3, 77);
            this.Size = new Size(551, 349);
        }

(二)实现“查看”菜单的单选功能

搜索了下,没有找到ToolStripMenuItem的设置互斥单选的属性设置,因此决定通过一个方法来实现。

namespace Calculators
{
   public static class AssistantFunctions
    {
      public static void SingleCheck(ToolStripMenuItem MenuItem)//实现菜单下拉菜单的单选效果
      {
         ToolStripMenuItem parentMenu = MenuItem.OwnerItem as ToolStripMenuItem;
         foreach (ToolStripMenuItem item in parentMenu.DropDownItems)
         {
             item.Checked = false;
         }
         MenuItem.Checked = true;
      }
    }
}

专门创建了一个 AssistantFunctions类,计划在这里存放所有以后可能在别的项目中共用的辅助方法。

当单击子菜单时,调用SingleCheck方法。如下:

  private void 标准型ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            AssistantFunctions.SingleCheck((ToolStripMenuItem)sender);
            ShowAsStandard();
        }

(三)计算方法类

设计了一个抽象的计算方法类Expression,Constant类和Operation类为继承自Expression类的实例方法。

namespace Calculators
{
     public abstract class Expression
    {
         public abstract double Evaluate();
    }
     public class Constant:Expression
     {
         double value;
         public Constant(double value)
         {
             this.value = value;
         }
         public override double Evaluate()
         {
             return value;
         }
     }
     public class Operation:Expression
     {
         Expression left;
         string op;
         Expression right;
         public Operation(Expression left,string op,Expression right)
         {
             this.left = left;
             this.op = op;
             this.right = right;


         }
         public override double Evaluate()
         {
             double x = left.Evaluate();
             double y =0 ;
             if (right!=null)
             {
                 y = right.Evaluate();
             }
             switch (op)
             {
                 case "+":
                     return x + y;
                 case "-":
                     return x - y;
                 case "*":
                     return x * y;
                 case "/":
                     return x / y;
                 case"√":
                     return Math.Sqrt(x);
                 case"%":
                     long result;
                     Math.DivRem((long)x,(long)y,out result);
                     return result;
                 case "1/x":
                     return 1/x;
                 default:
                     throw new InvalidOperationException();
             }
         }
     }
}

使用时,代码如下:

private Expression leftValue = null;//左操作数
string op;//操作符
Expression expression = null;//表达式对象

private void btnEvaluate_Click(object sender, EventArgs e)//按下等于号按钮
        {
           
            if (leftValue != null)
            {
                Constant RightVaue = new Constant(Convert.ToDouble(txtEnterBox.Text));//创建右操作数
                expression = new Operation(leftValue, op, RightVaue);//创建表达式
                leftValue = null;//清空左操作数
                txtEnterBox.Text = expression.Evaluate().ToString();
                
            }
            else
            {
                leftValue = new Constant(Convert.ToDouble(txtEnterBox.Text));//创建左操作数
            }
            txtExpression.Clear();
            txtEnterBoxClearFlag = true;
            btnBackSpaceEnableFlag = false;


        }

(四)确保输入内容合法的方法

在每次文本框内容发生改变时,通过正则表达式来判断刚刚输入的字符是否合法,如果不合法,则清除刚刚输入的内容。(不知道这样做是不是运算量太大),例如;

private void txtEnterBox_TextChanged(object sender, EventArgs e)
        {
            #region 检查输入数字是否规范
            if (Regex.IsMatch(txtEnterBox.Text, "^[0]+[1-9]+")) //1.非小数数字不能以0开头。
            {
                txtEnterBox.Text = Regex.Replace(txtEnterBox.Text, "^0+", "");
            }
            if (Regex.IsMatch(txtEnterBox.Text, "^0+"))//2.数字开头不能连续输入多个0,最多只能输入一个
            {
                txtEnterBox.Text = Regex.Replace(txtEnterBox.Text, "^0+", "0");
            }
            if (Regex.IsMatch(txtEnterBox.Text, "[.].*[.]"))//3.数字中小数点个数不能超过1
            {
                txtEnterBox.Text = Regex.Replace(txtEnterBox.Text, "[.]{1}$", "");
            }
            #endregion
        }

整个程序实现了“标准型”模式下最基本的加减乘除、取余、求倒数、求算数平方根和退格操作,“标准型”模式中加减乘除等运算符是没有优先级的,一律按照从左到右的顺序来计算。而“科学型”则需要实现运算符优先级,感觉比较复杂,还没想明白怎么做才好。对此,欢迎有好主意的朋友留言给我。微笑


原创粉丝点击