Making Tip Calculator for Window Phone 7
TL;DR To try out WP7 tools I made Tip Calcuator
The so-called business logic is very simple and is not very different among various versions of Tip Calcs out there. Yet, what I would like to show is my way of Metro UX which I do believe is still a part of family.
A few interesting bits: When Textboxes are pressed, they move up and down.
<Storyboard x:Name="mainInAnimation">
<DoubleAnimation Storyboard.TargetName="ContentPanel"
Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateX)"
Duration="0:0:1" To="-20" >
<DoubleAnimation.EasingFunction>
<ExponentialEase EasingMode="EaseOut" />
</DoubleAnimation.EasingFunction>
</DoubleAnimation>
<DoubleAnimation Storyboard.TargetName="TitlePanel"
Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateX)"
Duration="0:0:1" To="-20" >
<DoubleAnimation.EasingFunction>
<ExponentialEase EasingMode="EaseOut" />
</DoubleAnimation.EasingFunction>
</DoubleAnimation>
<DoubleAnimation Storyboard.TargetName="ContentPanel"
Storyboard.TargetProperty="Opacity" Duration="0:0:1.5" To="1">
<DoubleAnimation.EasingFunction>
<QuadraticEase EasingMode="EaseOut" />
</DoubleAnimation.EasingFunction>
</DoubleAnimation>
</Storyboard>
Styling
I have made a few changes to the default style.
- opacity of TexBox is 0.7
- different margins (careful with that and bear in mind the rule of thumb - 0.9mm
- alignment
- theme aware styles (like PhoneTextLargeStyle)
That is all about XAML, now C#.
public MainPage()
{
InitializeComponent();
this.LayoutUpdated += new EventHandler(MainPage_LayoutUpdated);
}
The ctor is kept light-weight for faster start of the app. All the details are handled by MainPage_LayoutUpdated
event handler.
private void MainPage_LayoutUpdated(object sender, EventArgs e)
{
if (m_onNavigatedToCalled)
{
m_onNavigatedToCalled = false;
Dispatcher.BeginInvoke(() =>
{
Random random = new Random();
var number = random.Next(1, 3);
string fileName = String.Format(@"Images\background{0}.jpg", number);
backgroundBrush.ImageSource = new BitmapImage(new Uri(fileName, UriKind.Relative));
radioButton3.IsChecked = true;
mainInAnimation.Begin();
});
}
}
Since we need to prepare things when everything is loaded MainPage_LayoutUpdated
is a proper event, but it’s called every time when layout has been updated, hence m_onNavigatedToCalled
flag is set to true and after first call it’s set to false. Dispatcher.BeginInvoke
is a thread-safe asynchronous method for UI changes (mainly). In lambda expression the random background is picked and animation begins (I prefer do it in code).
Orientation.
private void PhoneApplicationPage_OrientationChanged(object sender, OrientationChangedEventArgs e)
{
if ((e.Orientation & PageOrientation.Portrait) == PageOrientation.Portrait)
{
Grid.SetRow(bottom, 1);
Grid.SetColumn(bottom, 0);
sumStackPanel.Margin = new Thickness(35, 30, 0, 0);
}
else
{
Grid.SetRow(bottom, 0);
Grid.SetColumn(bottom, 1);
sumStackPanel.Margin = new Thickness(-5, 30, 0, 0);
}
}
To keep UI concise I have divided main Grid into 2 columns and 2 rows. After OrientationChanged
event occurs bottom grid is set to next column. For the orientation changes the Hybrid animation do a nice job.
And here is a demo. (animations are a bit choppy because of emulator + recording software) ;)
Feedback and comments are welcome.