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