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
Table of Content
- Introduction
- Download Windows Phone 7.1 (Mango)
- Let us look into the environment
- A look into the App.xaml and App.xaml.cs file
- A look into the MainPage.xaml file
- Modifying the xaml code for the Calculator
- Conclusion
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
- Web Installer for Windows Phone 7.1 Beta Tools - 3.4 MB
- Standalone/Offline installer for Windows Phone 7.1 Beta Tools (ISO image) - 717.81 MB
- Developer Tools Beta Release Note - 48 KB
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.
<
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 initializationInitializeComponent();
// Phone-specific initializationInitializePhoneApplication();
// 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 reactivatedprivate 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 launchedprivate 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 closingprivate 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 deactivatedprivate 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 debuggerSystem.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 failuresRootFrame.NavigationFailed += RootFrame_NavigationFailed;
// Ensure we don't initialize againphoneApplicationInitialized =
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 renderif (RootVisual != RootFrame)RootVisual = RootFrame;
// Remove this handler since it is no longer neededRootFrame.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.
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>
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.
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