Building a Calculator using WP 7.1(Mango)

Niladri.biswas
Posted by in Windows Phone category on for Beginner level | Points: 250 | Views : 10524 red flag
Rating: 5 out of 5  
 1 vote(s)

In this article, will create our first Windows Phone application with the "MANGO" flavour.This is the first in the series of article about Windows Phone 7.1 and our journey will begin from here with the making of a simple calculator in Windows Phone 7.1


 Download source code for Building a Calculator using WP 7.1(Mango)

Table of Content

  1. Introduction
  2. Download Windows Phone 7.1 (Mango)
  3. Let us look into the environment
  4. A look into the App.xaml and App.xaml.cs file
  5. A look into the MainPage.xaml file
  6. Modifying the xaml code for the Calculator
  7. Conclusion

Introduction

Windows Phone is a mobile operating system developed by Microsoft and it is the successor of Windows Mobile platform. On 24th May 2011, Microsoft launched Windows Phone 7.1 Developer Tools (code named "Mango") Beta. In this article, will create our first Windows Phone application with the "MANGO" flavour.This is the first in the series of article about Windows Phone 7.1 and our journey will begin from here with the making of a simple calculator in Windows Phone 7.1

Download Windows Phone 7.1 (Mango)

  1. Web Installer for Windows Phone 7.1 Beta Tools - 3.4 MB
  2. Standalone/Offline installer for Windows Phone 7.1 Beta Tools (ISO image) - 717.81 MB
  3. Developer Tools Beta Release Note - 48 KB

Let us look into the environment

After installation, let us open up Visual Studio and from the available templates, choose Silverlight for Windows Phone and choose Windows Phone Application.

After clicking on the OK button, we will be prompted as with which version we want to develop the application. We will, however, choose Windows Phone 7.1

And then click on OK button and we will be presented with the below

Let us now look into the project structure

We can figure out that we have 3 image files and two xaml files as App.xaml and MainPage.xaml and its associated code behind files.

A look into the App.xaml and App.xaml.cs file

<Application

x:Class="SimpleCalculator.App"

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"

xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone">

<!--Application Resources-->

<Application.Resources>

</Application.Resources>

<Application.ApplicationLifetimeObjects>

<!--Required object that handles lifetime events for the application-->

<shell:PhoneApplicationService

Launching="Application_Launching" Closing="Application_Closing"

Activated="Application_Activated" Deactivated="Application_Deactivated"/>

</Application.ApplicationLifetimeObjects>

</Application>

The keyword Application tells the compiler that the Application definition is contain in this XAML.

The lines

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 

xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"

xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"

indicates the namespace and class name is for this particular file.They allows us to use the functionalities present in .NET namespaces directly in the XAML.

The next pair of line indicates the resources

<!--Application Resources-->

<Application.Resources>

</Application.Resources>

Resources are reusable items e.g. brushes,templates,styles (like Asp.net CSS files) that can be use across XAML files.

The next section is the ApplicationLifetimeObjects

<Application.ApplicationLifetimeObjects>

<!--Required object that handles lifetime events for the application-->

<shell:PhoneApplicationService

Launching="Application_Launching" Closing="Application_Closing"

Activated="Application_Activated" Deactivated="Application_Deactivated"/>

</Application.ApplicationLifetimeObjects>

This section allows us to extend the application model without requiring specialized Application subclasses. Applications can continue to inherit the Application class directly, and can add extensions by populating the ApplicationLifetimeObjects list. Applications can do this in the class constructor or in the application XAML.The standard extension present in WP7.1 is the PhoneApplicationService that provides access to methods that are associated with various aspects of the application's lifetime.We can find attributes(like Launching,Closing,Activated,Deactivated) and their corresponding events(like Application_Launching,Application_Closing,Application_Activated,Application_Deactivated.

Now let us see the contents of App.xaml.cs file

RootFrame property

public PhoneApplicationFrame RootFrame { get; private set; }

The Windows Phone pages are accessible through this property since they all are displayed inside a frame

Constructor

public App()

{

// Global handler for uncaught exceptions.

UnhandledException += Application_UnhandledException;

// Standard Silverlight initialization

InitializeComponent();

// Phone-specific initialization

InitializePhoneApplication();

// Show graphics profiling information while debugging.

if (System.Diagnostics.Debugger.IsAttached)

{

// Display the current frame rate counters.

Application.Current.Host.Settings.EnableFrameRateCounter = true;

// Show the areas of the app that are being redrawn in each frame.

//Application.Current.Host.Settings.EnableRedrawRegions = true;

// Enable non-production analysis visualization mode,

// which shows areas of a page that are handed off to GPU with a colored overlay.

//Application.Current.Host.Settings.EnableCacheVisualization = true;

// Disable the application idle detection by setting the UserIdleDetectionMode property of the

// application's PhoneApplicationService object to Disabled.

// Caution:- Use this under debug mode only. Application that disable user idle detection will continue to run

// and consume battery power when the user is not using the phone.

PhoneApplicationService.Current.UserIdleDetectionMode = IdleDetectionMode.Disabled;

}

}

This is the constructor for the App class and is called as soon as the application is initialised.

The UnhandledException line provides a top-level error handler which is guaranteed to be called

We will not find any implementation of the InitializeComponent method at this time. When the application is compile,the code will be created in the .g.cs file and we will find the implementation of InitializeComponent over there

The next line calls the InitializePhoneApplication method

The next section shows the behaviour of the application when the debugger is attached.

// Code to execute when the application is launching (eg, from Start)

// This code will not execute when the application is reactivated

private void Application_Launching(object sender, LaunchingEventArgs e)

{

}

 

// Code to execute when the application is activated (brought to foreground)

// This code will not execute when the application is first launched

private void Application_Activated(object sender, ActivatedEventArgs e)

{

}

 

// Code to execute when the application is deactivated (sent to background)

// This code will not execute when the application is closing

private void Application_Deactivated(object sender, DeactivatedEventArgs e)

{

}

 

// Code to execute when the application is closing (eg, user hit Back)

// This code will not execute when the application is deactivated

private void Application_Closing(object sender, ClosingEventArgs e)

{

}

These are the methods that were hooked up as part of the PhoneApplicationService extensions

private void RootFrame_NavigationFailed(object sender, NavigationFailedEventArgs e)

{

if (System.Diagnostics.Debugger.IsAttached)

{

// A navigation has failed; break into the debugger

System.Diagnostics.Debugger.Break();

}

}

Code to execute if a navigation fails and the debugger is break

private bool phoneApplicationInitialized = false;

 

// Do not add any additional code to this method

private void InitializePhoneApplication()

{

if (phoneApplicationInitialized)

return;

// Create the frame but don't set it as RootVisual yet; this allows the splash

// screen to remain active until the application is ready to render.

RootFrame = new PhoneApplicationFrame();

RootFrame.Navigated += CompleteInitializePhoneApplication;

// Handle navigation failures

RootFrame.NavigationFailed += RootFrame_NavigationFailed;

// Ensure we don't initialize again

phoneApplicationInitialized = true;

}

 

// Do not add any additional code to this method

private void CompleteInitializePhoneApplication(object sender, NavigationEventArgs e)

{

// Set the root visual to allow the application to render

if (RootVisual != RootFrame)

RootVisual = RootFrame;

// Remove this handler since it is no longer needed

RootFrame.Navigated -= CompleteInitializePhoneApplication;

}

The phoneApplicationInitialized property ensure that the application is called only once. The RootFrame property is initialized and the Navigated and NavigationFailed events are hooked up. Finally, the root visual object is set to be the root frame and the navigated event is dereferenced.

A look into the MainPage.xaml file

Before going to explain anything on this, let us first run the aplication at it's default state

Now let us look into the xaml code

<phone:PhoneApplicationPage

x:Class="SimpleCalculator.MainPage"

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"

xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"

xmlns:d="http://schemas.microsoft.com/expression/blend/2008"

xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"

mc:Ignorable="d" d:DesignWidth="480" d:DesignHeight="768"

FontFamily="{StaticResource PhoneFontFamilyNormal}"

FontSize="{StaticResource PhoneFontSizeNormal}"

Foreground="{StaticResource PhoneForegroundBrush}"

SupportedOrientations="Portrait" Orientation="Portrait"

shell:SystemTray.IsVisible="True">

<!--LayoutRoot is the root grid where all page content is placed-->

<Grid x:Name="LayoutRoot" Background="Transparent">

<Grid.RowDefinitions>

<RowDefinition Height="Auto"/>

<RowDefinition Height="*"/>

</Grid.RowDefinitions>

<!--TitlePanel contains the name of the application and page title-->

<StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">

<TextBlock x:Name="ApplicationTitle" Text="MY APPLICATION" Style="{StaticResource PhoneTextNormalStyle}"/>

<TextBlock x:Name="PageTitle" Text="page name" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>

</StackPanel>

<!--ContentPanel - place additional content here-->

<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0"></Grid>

</Grid>

<!--Sample code showing usage of ApplicationBar-->

<!--<phone:PhoneApplicationPage.ApplicationBar>

<shell:ApplicationBar IsVisible="True" IsMenuEnabled="True">

<shell:ApplicationBarIconButton IconUri="/Images/appbar_button1.png" Text="Button 1"/>

<shell:ApplicationBarIconButton IconUri="/Images/appbar_button2.png" Text="Button 2"/>

<shell:ApplicationBar.MenuItems>

<shell:ApplicationBarMenuItem Text="MenuItem 1"/>

<shell:ApplicationBarMenuItem Text="MenuItem 2"/>

</shell:ApplicationBar.MenuItems>

</shell:ApplicationBar>

</phone:PhoneApplicationPage.ApplicationBar>-->

</phone:PhoneApplicationPage>

The very first line

phone:PhoneApplicationPage

indicates that the phone page inherit from the PhoneApplicationPage type

Then the xmlns tells us the dotnet namespaces this xaml file uses

The

FontFamily="{StaticResource PhoneFontFamilyNormal}"

FontSize="{StaticResource PhoneFontSizeNormal}"

Foreground="{StaticResource PhoneForegroundBrush}"

are the resource files

Then comes the grid layout where the UI elements are being defined.The design has a Grid with 2 rows.The first one is to set the title of the page

<!--TitlePanel contains the name of the application and page title-->

<StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">

<TextBlock x:Name="ApplicationTitle" Text="MY APPLICATION" Style="{StaticResource PhoneTextNormalStyle}"/>

<TextBlock x:Name="PageTitle" Text="page name" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>

</StackPanel>

and the second one is to set the content of the page.

<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0"></Grid>

Modifying the xaml code for the Calculator

Now let us modify the xaml code that will be needed to build the Calculator

<phone:PhoneApplicationPage

x:Class="SimpleCalculator.MainPage"

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"

xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"

xmlns:d="http://schemas.microsoft.com/expression/blend/2008"

xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"

mc:Ignorable="d" d:DesignWidth="480" d:DesignHeight="768"

FontFamily="{StaticResource PhoneFontFamilyNormal}"

FontSize="{StaticResource PhoneFontSizeNormal}"

Foreground="{StaticResource PhoneForegroundBrush}"

SupportedOrientations="Portrait" Orientation="Portrait"

shell:SystemTray.IsVisible="True">

<!--LayoutRoot is the root grid where all page content is placed-->

<Grid x:Name="LayoutRoot" Background="Transparent">

<Grid.ColumnDefinitions>

<ColumnDefinition></ColumnDefinition>

<ColumnDefinition></ColumnDefinition>

<ColumnDefinition></ColumnDefinition>

<ColumnDefinition></ColumnDefinition>

<ColumnDefinition></ColumnDefinition>

<ColumnDefinition></ColumnDefinition>

</Grid.ColumnDefinitions>

<Grid.RowDefinitions>

<RowDefinition></RowDefinition>

<RowDefinition></RowDefinition>

<RowDefinition></RowDefinition>

<RowDefinition></RowDefinition>

<RowDefinition></RowDefinition>

<RowDefinition></RowDefinition>

</Grid.RowDefinitions>

<TextBox Name="txtCalculation" Grid.ColumnSpan="6" Background="Ivory" TextAlignment="Right" IsReadOnly="True" Text="0" Margin="0,0,0,36"></TextBox>

<TextBlock Grid.Column="0" Grid.Row="1" Name="lblMemStorage"></TextBlock>

<Button Name="btnBackspace" Grid.Row="1" Grid.Column="1" Grid.ColumnSpan="3" Content="Backspace" Margin="36,0,0,47" />

<Button Name="btnCE" Grid.Row="1" Grid.Column="4" Content="CE" Margin="0,0,0,47" />

<Button Name="btnClear" Grid.Row="1" Grid.Column="5" Content="C" Margin="0,0,0,47" />

<Button Name="btnMemClear" Grid.Row="2" Content="MC" Margin="0,0,67,33" Grid.ColumnSpan="2" />

<Button Name="btn7" Grid.Row="2" Grid.Column="1" Content="7" Margin="0,0,0,33" />

<Button Name="btn8" Grid.Row="2" Grid.Column="2" Content="8" Margin="0,0,0,33" />

<Button Name="btn9" Grid.Row="2" Grid.Column="3" Content="9" Margin="0,0,0,33" />

<Button Name="btnDiv" Grid.Row="2" Grid.Column="4" Content="/" Margin="0,0,0,33" />

<Button Name="btnSqrt" Grid.Row="2" Grid.Column="5" Content="Sqrt" Margin="0,0,0,33" />

<Button Name="btnMemRecall" Grid.Row="3" Content="MR" Margin="0,0,67,33" Grid.ColumnSpan="2" />

<Button Name="btn4" Grid.Row="3" Grid.Column="1" Content="4" Margin="0,0,0,33" />

<Button Name="btn5" Grid.Row="3" Grid.Column="2" Content="5" Margin="0,0,0,33" />

<Button Name="btn6" Grid.Row="3" Grid.Column="3" Content="6" Margin="0,0,0,33" />

<Button Name="btnMul" Grid.Row="3" Grid.Column="4" Content="*" Margin="0,0,0,33" />

<Button Name="btnPercentile" Grid.Row="3" Grid.Column="5" Content="%" Margin="0,0,0,33" />

<Button Name="btnMemStore" Grid.Row="4" Content="MS" Margin="0,0,67,34" Grid.ColumnSpan="2" />

<Button Name="btn1" Grid.Row="4" Grid.Column="1" Content="1" Margin="0,0,0,34" />

<Button Name="btn2" Grid.Row="4" Grid.Column="2" Content="2" Margin="0,0,0,34" />

<Button Name="btn3" Grid.Row="4" Grid.Column="3" Content="3" Margin="0,0,0,34" />

<Button Name="btnMinus" Grid.Row="4" Grid.Column="4" Content="-" Margin="0,0,0,34" />

<Button Name="btnInverse" Grid.Row="4" Grid.Column="5" Content="1/x" Margin="0,0,-11,34" />

<Button Name="btnMemPlus" Grid.Row="5" Content="M+" Margin="0,0,67,36" Grid.ColumnSpan="2" />

<Button Name="btn0" Grid.Row="5" Grid.Column="1" Content="0" Margin="0,0,0,36" />

<Button Name="btnPlusMinus" Grid.Row="5" Grid.Column="2" Content="+/-" Margin="0,0,66,36" Grid.ColumnSpan="2" />

<Button Name="btnDecimal" Grid.Row="5" Grid.Column="3" Content="." Margin="0,0,0,36" />

<Button Name="btnPlus" Grid.Row="5" Grid.Column="4" Content="+" Margin="0,0,0,36" />

<Button Name="btnEqual" Grid.Row="5" Grid.Column="5" Content="=" Margin="0,0,0,36" />

</Grid>

</phone:PhoneApplicationPage>

Now if we run the application, it will look as under

So far the implementation part is concern, it is quite simple. We have an interface where we have defined all the operations.

public interface IOperation

{

string Backspace(string value);

string DigitInsertion(string oldValue, string newValue);

string Calculate(string firstNumber, string secondNumber, string Operator);

string Clear(string value);

string DecimalInsertion(string oldValue, string decimalValue);

}

The concrete class CalciOperation.cs implements the interface.

Conclusion

In this article, we have learnt about the default project structure of WP 7.1 , details of app.xaml and app.xaml.cs files and also we have see the meaning of the default xaml code of MainPage.xaml. Also we have created a simple calculator project and have seen it's behaviour in the emulator.

Hope this is useful. The application is attached herewith.

Thanks for reading

Page copy protected against web site content infringement by Copyscape

About the Author

Niladri.biswas
Full Name: Niladri Biswas
Member Level: Platinum
Member Status: Member
Member Since: 10/25/2010 11:04:24 AM
Country: India
Best Regards, Niladri Biswas
http://www.dotnetfunda.com
Technical Lead at HCL Technologies

Login to vote for this post.

Comments or Responses

Login to post response

Comment using Facebook(Author doesn't get notification)