Silverlight版的计算器,功能全面
1.PaperTrail.cs
/// <summary>
/// 输入框处理类
/// </summary>
public class PaperTrail
{
string args;
private TextBox PaperBox;
public PaperTrail()
{
}
public PaperTrail(TextBox paperBox)
{
PaperBox = paperBox;
}
public void AddArguments(string a)
{
args = a;
}
public void AddResult(string r)
{
PaperBox.Text += args + " = " + r + "\n";
PaperBox.IsEnabled = false;
}
public void Clear()
{
PaperBox.Text = args = string.Empty;
}
}
public class Operations
{
private static Operation _BPlus = new Operation("BPlus");
public static Operation BPlus()
{
return _BPlus;
public class Operation
{
// constructor logic
public Operation(string name)
{
this.Name = name;
}
// Name
private string _name;
public string Name
{
get { return _name; }
set { _name = value; }
}
}
前台
<UserControl x:Class="CalculatorProject.MainPage"
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"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="400" Width="600" Height="400">
<Border Height="366" Width="586" BorderBrush="#FF384452" BorderThickness="0,0,0,0" Background="Green">
<Grid Name="MyGrid">
<Grid.Resources>
<Style x:Key="DigitBtn" TargetType="Button" >
<Setter Property="FontSize" Value="14" />
<Setter Property="Margin" Value="5" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button" xmlns:vsm="clr-namespace:System.Windows;assembly=System.Windows">
<Grid>
<vsm:VisualStateManager.VisualStateGroups>
<vsm:VisualStateGroup x:Name="CommonStates">
<vsm:VisualState x:Name="Normal"/>
<vsm:VisualState x:Name="MouseOver">
<Storyboard>
<ColorAnimation Duration="0" Storyboard.TargetName="TB" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)" To="#FF8DDDF1"/>
</Storyboard>
</vsm:VisualState>
<vsm:VisualState x:Name="Pressed">
<Storyboard>
<ColorAnimation Duration="0" Storyboard.TargetName="TB" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)" To="#FF6DBDD1"/>
</Storyboard>
</vsm:VisualState>
<vsm:VisualState x:Name="Disabled">
<Storyboard>
<DoubleAnimation Duration="0" Storyboard.TargetName="DisabledVisualElement" Storyboard.TargetProperty="Opacity" To=".55"/>
</Storyboard>
</vsm:VisualState>
</vsm:VisualStateGroup>
<vsm:VisualStateGroup x:Name="FocusStates">
<vsm:VisualState x:Name="Focused" />
<vsm:VisualState x:Name="Unfocused" />
</vsm:VisualStateGroup>
</vsm:VisualStateManager.VisualStateGroups>
<Rectangle x:Name="TB" Fill="{TemplateBinding Background}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" RadiusX="6" RadiusY="6" />
<ContentPresenter Content="{TemplateBinding Content}" HorizontalAlignment="Center" VerticalAlignment="Center" />
<Rectangle x:Name="DisabledVisualElement" RadiusX="3" RadiusY="3" Fill="#FFFFFFFF" Opacity="0" IsHitTestVisible="false" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Grid.Resources>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Button Name="B7" Click="DigitBtn_Click" Background="Lightgray" Style="{StaticResource DigitBtn}" Grid.Column="4" Grid.Row="2" Content="7" />
<Button Name="B8" Click="DigitBtn_Click" Background="Lightgray" Style="{StaticResource DigitBtn}" Grid.Column="5" Grid.Row="2" Content="8" />
<Button Name="B9" Click="DigitBtn_Click" Background="Lightgray" Style="{StaticResource DigitBtn}" Grid.Column="6" Grid.Row="2" Content="9" />
<Button Name="B4" Click="DigitBtn_Click" Background="Lightgray" Style="{StaticResource DigitBtn}" Grid.Column="4" Grid.Row="3" Content="4" />
<Button Name="B5" Click="DigitBtn_Click" Background="Lightgray" Style="{StaticResource DigitBtn}" Grid.Column="5" Grid.Row="3" Content="5" />
<Button Name="B6" Click="DigitBtn_Click" Background="Lightgray" Style="{StaticResource DigitBtn}" Grid.Column="6" Grid.Row="3" Content="6" />
<Button Name="B1" Click="DigitBtn_Click" Background="Lightgray" Style="{StaticResource DigitBtn}" Grid.Column="4" Grid.Row="4" Content="1" />
<Button Name="B2" Click="DigitBtn_Click" Background="Lightgray" Style="{StaticResource DigitBtn}" Grid.Column="5" Grid.Row="4" Content="2" />
<Button Name="B3" Click="DigitBtn_Click" Background="Lightgray" Style="{StaticResource DigitBtn}" Grid.Column="6" Grid.Row="4" Content="3" />
<Button Name="B0" Click="DigitBtn_Click" Background="Lightgray" Style="{StaticResource DigitBtn}" Grid.Column="4" Grid.Row="5" Content="0" />
<Button Name="BPeriod" Click="DigitBtn_Click" Background="Lightgray" Style="{StaticResource DigitBtn}" Grid.Column="5" Grid.Row="5" Content="."/>
<Button Name="BPM" Click="OperBtn_Click" Background="Darkgray" Style="{StaticResource DigitBtn}" Grid.Column="6" Grid.Row="5" Content="+/-"/>
<Button Name="BDevide" Click="OperBtn_Click" Background="Darkgray" Style="{StaticResource DigitBtn}" Grid.Column="7" Grid.Row="2" Content="/"/>
<Button Name="BMultiply" Click="OperBtn_Click" Background="Darkgray" Style="{StaticResource DigitBtn}" Grid.Column="7" Grid.Row="3" Content="*"/>
<Button Name="BMinus" Click="OperBtn_Click" Background="Darkgray" Style="{StaticResource DigitBtn}" Grid.Column="7" Grid.Row="4" Content="-"/>
<Button Name="BPlus" Click="OperBtn_Click" Background="Darkgray" Style="{StaticResource DigitBtn}" Grid.Column="7" Grid.Row="5" Content="+"/>
<Button Name="BSqrt" Click="OperBtn_Click" Background="Darkgray" Style="{StaticResource DigitBtn}" Grid.Column="8" Grid.Row="2" Content="Sqrt"/>
<Button Name="BPercent" Click="OperBtn_Click" Background="Darkgray" Style="{StaticResource DigitBtn}" Grid.Column="8" Grid.Row="4" Content="%"/>
<Button Name="BOneOver" Click="OperBtn_Click" Background="Darkgray" Style="{StaticResource DigitBtn}" Grid.Column="8" Grid.Row="3" Content="1/X"/>
<Button Name="BEqual" Click="OperBtn_Click" Background="Darkgray" Style="{StaticResource DigitBtn}" Grid.Column="8" Grid.Row="5" Content="="/>
<Button Name="BC" Click="OperBtn_Click" Background="Darkgray" Style="{StaticResource DigitBtn}" Grid.Column="8" Grid.Row="1" Grid.ColumnSpan="1" Content="C"/>
<Button Name="BCE" Click="OperBtn_Click" Background="Darkgray" Style="{StaticResource DigitBtn}" Grid.Column="7" Grid.Row="1" Grid.ColumnSpan="1" Content="CE"/>
<Button Name="BMemClear" Click="OperBtn_Click" Background="Darkgray" Style="{StaticResource DigitBtn}" Grid.Column="3" Grid.Row="2" Content="MC"/>
<Button Name="BMemRecall" Click="OperBtn_Click" Background="Darkgray" Style="{StaticResource DigitBtn}" Grid.Column="3" Grid.Row="3" Content="MR"/>
<Button Name="BMemSave" Click="OperBtn_Click" Background="Darkgray" Style="{StaticResource DigitBtn}" Grid.Column="3" Grid.Row="4" Content="MS"/>
<Button Name="BMemPlus" Click="OperBtn_Click" Background="Darkgray" Style="{StaticResource DigitBtn}" Grid.Column="3" Grid.Row="5" Content="M+"/>
<TextBlock Name="BMemBox" Grid.Column="3" Grid.Row="1" Margin="10,17,10,17" Grid.ColumnSpan="2">Memory: [empty]</TextBlock>
</Grid>
</Border>
</UserControl>
后台
public partial class MainPage : UserControl
{
public MainPage()
{
InitializeComponent();
DisplayBox = new TextBox();
Grid.SetRow(DisplayBox, 0);
Grid.SetColumn(DisplayBox, 0);
Grid.SetColumnSpan(DisplayBox, 9);
DisplayBox.Height = 36;
DisplayBox.FontSize = 18;
DisplayBox.TextAlignment = TextAlignment.Right;
DisplayBox.FontWeight = FontWeights.Bold;
MyGrid.Children.Add(DisplayBox);
PaperBox = new TextBox();
Grid.SetRow(PaperBox, 500);
Grid.SetColumn(PaperBox, 0);
Grid.SetColumnSpan(PaperBox, 3);
Grid.SetRowSpan(PaperBox, 5);
PaperBox.IsReadOnly = true;
PaperBox.VerticalScrollBarVisibility = ScrollBarVisibility.Visible;
PaperBox.Margin = new Thickness(3.0, 1.0, 1.0, 1.0);
PaperBox.HorizontalScrollBarVisibility = ScrollBarVisibility.Auto;
Paper = new PaperTrail(PaperBox);
MyGrid.Children.Add(PaperBox);
ProcessKey('0');
EraseDisplay = true;
}
private TextBox DisplayBox;
private TextBox PaperBox;
private PaperTrail Paper;
/// <summary>
/// 操作类型
/// </summary>
private enum Operation
{
None,
Devide,
Multiply,
Subtract,
Add,
Percent,
Sqrt,
OneX,
Negate
}
private Operation LastOper;
private string _display;
private string _last_val;
private string _mem_val;
private bool _erasediplay;
//标识当前值
private bool EraseDisplay
{
get
{
return _erasediplay;
}
set
{
_erasediplay = value;
}
}
//获取或设置记忆的值
private Double Memory
{
get
{
if (_mem_val == string.Empty)
return 0.0;
else
return Convert.ToDouble(_mem_val);
}
set
{
_mem_val = value.ToString();
}
}
//最后输入的值
private string LastValue
{
get
{
if (_last_val == string.Empty)
return "0";
return _last_val;
}
set
{
_last_val = value;
}
}
//当前显示字符串
private string Display
{
get
{
return _display;
}
set
{
_display = value;
}
}
private void OnWindowKeyDown(object sender, System.Windows.Input.KeyEventArgs e)
{
string s = e.Key.ToString();
char c = (s.ToCharArray())[0];
e.Handled = true;
if ((c >= '0' && c <= '9') || c == '.' || c == '\b') // '\b' is backspace
{
ProcessKey(c);
return;
}
switch (c)
{
case '+':
ProcessOperation("BPlus");
break;
case '-':
ProcessOperation("BMinus");
break;
case '*':
ProcessOperation("BMultiply");
break;
case '/':
ProcessOperation("BDevide");
break;
case '%':
ProcessOperation("BPercent");
break;
case '=':
ProcessOperation("BEqual");
break;
}
}
private void DigitBtn_Click(object sender, RoutedEventArgs e)
{
string s = ((Button)sender).Content.ToString();
char[] ids = s.ToCharArray();
ProcessKey(ids[0]);
}
private void ProcessKey(char c)
{
if (EraseDisplay)
{
Display = string.Empty;
EraseDisplay = false;
}
AddToDisplay(c);
}
private void ProcessOperation(string s)
{
Double d = 0.0;
switch (s)
{
case "BPM":
LastOper = Operation.Negate;
LastValue = Display;
CalcResults();
LastValue = Display;
EraseDisplay = true;
LastOper = Operation.None;
break;
case "BDevide":
if (EraseDisplay)
{
LastOper = Operation.Devide;
break;
}
CalcResults();
LastOper = Operation.Devide;
LastValue = Display;
EraseDisplay = true;
break;
case "BMultiply":
if (EraseDisplay)
{
LastOper = Operation.Multiply;
break;
}
CalcResults();
LastOper = Operation.Multiply;
LastValue = Display;
EraseDisplay = true;
break;
case "BMinus":
if (EraseDisplay)
{
LastOper = Operation.Subtract;
break;
}
CalcResults();
LastOper = Operation.Subtract;
LastValue = Display;
EraseDisplay = true;
break;
case "BPlus":
if (EraseDisplay)
{
LastOper = Operation.Add;
break;
}
CalcResults();
LastOper = Operation.Add;
LastValue = Display;
EraseDisplay = true;
break;
case "BEqual":
if (EraseDisplay)
break;
CalcResults();
EraseDisplay = true;
LastOper = Operation.None;
LastValue = Display;
break;
case "BSqrt":
LastOper = Operation.Sqrt;
LastValue = Display;
CalcResults();
LastValue = Display;
EraseDisplay = true;
LastOper = Operation.None;
break;
case "BPercent":
if (EraseDisplay)
{
LastOper = Operation.Percent;
break;
}
CalcResults();
LastOper = Operation.Percent;
LastValue = Display;
EraseDisplay = true;
break;
case "BOneOver":
LastOper = Operation.OneX;
LastValue = Display;
CalcResults();
LastValue = Display;
EraseDisplay = true;
LastOper = Operation.None;
break;
case "BC":
LastOper = Operation.None;
Display = LastValue = string.Empty;
Paper.Clear();
UpdateDisplay();
break;
case "BCE":
LastOper = Operation.None;
Display = LastValue;
UpdateDisplay();
break;
case "BMemClear":
Memory = 0.0F;
DisplayMemory();
break;
case "BMemSave":
Memory = Convert.ToDouble(Display);
DisplayMemory();
EraseDisplay = true;
break;
case "BMemRecall":
Display = Memory.ToString();
UpdateDisplay();
EraseDisplay = false;
break;
case "BMemPlus":
d = Memory + Convert.ToDouble(Display);
Memory = d;
DisplayMemory();
EraseDisplay = true;
break;
}
}
private void OperBtn_Click(object sender, RoutedEventArgs e)
{
ProcessOperation(((Button)sender).Name.ToString());
}
private double Calc(Operation LastOper)
{
double d = 0.0;
try
{
switch (LastOper)
{
case Operation.Devide:
Paper.AddArguments(LastValue + " / " + Display);
d = (Convert.ToDouble(LastValue) / Convert.ToDouble(Display));
CheckResult(d);
Paper.AddResult(d.ToString());
break;
case Operation.Add:
Paper.AddArguments(LastValue + " + " + Display);
d = Convert.ToDouble(LastValue) + Convert.ToDouble(Display);
CheckResult(d);
Paper.AddResult(d.ToString());
break;
case Operation.Multiply:
Paper.AddArguments(LastValue + " * " + Display);
d = Convert.ToDouble(LastValue) * Convert.ToDouble(Display);
CheckResult(d);
Paper.AddResult(d.ToString());
break;
case Operation.Percent:
Paper.AddArguments(LastValue + " % " + Display);
d = (Convert.ToDouble(LastValue) * Convert.ToDouble(Display)) / 100.0F;
CheckResult(d);
Paper.AddResult(d.ToString());
break;
case Operation.Subtract:
Paper.AddArguments(LastValue + " - " + Display);
d = Convert.ToDouble(LastValue) - Convert.ToDouble(Display);
CheckResult(d);
Paper.AddResult(d.ToString());
break;
case Operation.Sqrt:
Paper.AddArguments("Sqrt( " + LastValue + " )");
d = Math.Sqrt(Convert.ToDouble(LastValue));
CheckResult(d);
Paper.AddResult(d.ToString());
break;
case Operation.OneX:
Paper.AddArguments("1 / " + LastValue);
d = 1.0F / Convert.ToDouble(LastValue);
CheckResult(d);
Paper.AddResult(d.ToString());
break;
case Operation.Negate:
d = Convert.ToDouble(LastValue) * (-1.0F);
break;
}
}
catch
{
d = 0;
MessageBox.Show("Operation cannot be perfomed");
}
return d;
}
private void CheckResult(double d)
{
if (Double.IsNegativeInfinity(d) || Double.IsPositiveInfinity(d) || Double.IsNaN(d))
throw new Exception("Illegal value");
}
private void DisplayMemory()
{
if (_mem_val != String.Empty)
BMemBox.Text = "Memory: " + _mem_val;
else
BMemBox.Text = "Memory: [empty]";
}
private void CalcResults()
{
double d;
if (LastOper == Operation.None)
return;
d = Calc(LastOper);
Display = d.ToString();
UpdateDisplay();
}
private void UpdateDisplay()
{
if (String.IsNullOrEmpty(Display))
DisplayBox.Text = "0";
else
DisplayBox.Text = Display;
}
private void AddToDisplay(char c)
{
if (c == '.')
{
if (Display.IndexOf('.', 0) >= 0) //already exists
return;
Display = Display + c;
}
else
{
if (c >= '0' && c <= '9')
{
Display = Display + c;
}
else
if (c == '\b')
{
if (Display.Length <= 1)
Display = String.Empty;
else
{
int i = Display.Length;
Display = Display.Remove(i - 1, 1);
}
}
}
UpdateDisplay();
}
}