I wrote a capsule size power booster that may help you to be an intermediate Windows Phone app developer from some knowledge of Visual Studio style solution development. After I have discovered a lot of demand, I decided to post it as an article instead of a pdf.

Assuming Reader’s Zero Idea About Windows Phone

Microsoft’s entrance to the smartphone market dates back to year 2000 with the debut of Pocket PC 2000, the original forefather of the Windows Mobile and great grandfather of Windows Phone. Unlike its forefathers, it is primarily aimed at the consumer market rather than the enterprise market. Microsoft offers a new user interface with Windows Phone with its design language named Metro, integrates the operating system with third party and other Microsoft services, and controls the hardware it runs on. They also believe same software excellence can be delivered without selling a dedicated device, so Windows Phone is just a mobile operating system rather than a dedicated phone like iPhone.

Windows Phone 7 (now 8): A new kind of phone

Microsoft has come up with a brand new concept of phone. They have taken nothing from the predecessor or the competitors. When given the chance for a fresh start, the Windows Phone design team drew from many sources of inspiration to determine the guiding principles for the next generation phone interface. Sources included Swiss influenced print and packaging with its emphasis on simplicity, way-finding graphics found in transportation hubs and other Microsoft software such as Zune, Office Labs and games with a strong focus on motion and content over chrome.

image Nokia-Lumia-920  htc_8x_official_04

This is a completely new start in terms of user interface and user experience. A specially-made version of Microsoft's Segoe font family, Segoe WP, is used as the main font family for all typographical elements. The Metro design language was designed specifically to consolidate groups of common tasks to speed up usage. This is accomplished by excluding superfluous graphics and instead relying on the actual content to also function as the main UI. The resulting interfaces favor larger hubs over smaller buttons and often feature laterally scrolling full bleed canvases. Page titles are usually large and consequently also take advantage of lateral scrolling.

image

Animation plays a large part, with transitions, and user interactions such as presses or swipes recommended to always be acknowledged by some form of natural animation or motion. This is intended to give the user the impression that the UI is "alive" and responsive, with "an added sense of depth." The same Metro language is being applied in Windows 8, XBOX and Windows Live as well.

Platform and Tools for App Development

Microsoft’s all development platforms and tools are based on .NET and Visual Studio respectively. Windows Phone’s are no exception. Windows Phone tooling gives all that you need, including new Visual Studio project types, integrated Phone emulator to run, test, set breakpoints and debug your apps. You can build apps and games using: Silverlight, suitable for regular apps, and XNA Framework, which is suitable for high performance graphics rendering such as games. We will focus on apps only in here, so expect no XNA coverage. Navigate to http://dev.windowsphone.com and grab the free tools. That’s all you need! Class library reference if you feel like start hacking now: http://bit.ly/dq0uqf!

First Project: Solution Structure

File -> New -> Project –> Windows Phone -> Windows Phone Application. After the solution has been prepared for you, first thing that should catch your eyes is the MainPage.xaml. This is equivalent of Default.aspx if you are from Web background, and Form1.cs if you are a Windows Forms guy or girl. So far so good. But, like Web form, it has a XML-like view (known as XAML) and a codebehind.

Let’s open the XAML file. XAML is an extensible version of XML format particularly designed for constructing WPF and Silverlight user interfaces. Learn XAML from here: http://bit.ly/sNzLza. Like regular XML schema references you will also find many in that XAML file. They are required for resources and controls are used in the page, much like control namespaces referenced in the WebForms. You will notice that there is a root element, like XML must have one, named Grid with x:Name=“LayoutRoot.” Yes, that’s how you name an element (call them controls if you will). Obviously, you do have the same Toolbox, Properties, Solution Explorer and similar design experiences as WebForms and Windows Forms. Scroll a bit, and you will see three elements, two of which make sense to us: Two TextBlocks having ApplicationTitle and PageTitle. TextBlocks are Labels, only more powerful! Last thing we see is another Grid named ContentPanel.

Hello World

imageNow drag and drop a Button element into that Grid, and see how the XAML changes accordingly. Double click the Button and as you expect it will open the

codebehind window for you to write an even handler for button click. We will start with a hello to the world:

MessageBox.Show("Hello World!");

Let’s go ahead and enhance this a bit. Give the ‘page title’ TextBlock a name, say “PageTitle.” Drop a TextBox, Button and WebBrowser control with name txtUrl, btnGo and browser respectively. Add some code:

private void btnGo_Click(object sender, RoutedEventArgs e) 
{ 
    if (string.IsNullOrWhiteSpace(txtUrl.Text)) 
    { 
        MessageBox.Show("Please type an URL first."); 
        return; 
    }

    PageTitle.Text = "Loading..."; 
    browser.Navigate(new Uri(txtUrl.Text)); 
    }

private void browser_LoadCompleted(object sender, NavigationEventArgs e) 
{ 
    PageTitle.Text = "Completed."; 
}

Congratulations! You have built your first app.

Do More Hacks

  1. Show your own HTML instead of a webpage:    
    browser.NavigateToString("<html><body><h1>Good morning! 
    Where's my PC?</h1></body></html>"
    );
  2. Call JavaScript method from within your app:      
    browser.InvokeScript("my_cool_method", "parameter1", 
    "parameter2", "parameterN");
  3. Get notified by an event in the app, on a call from JavaScript code:      
    browser.ScriptNotify

Fun with Maps

Let us have some fun with Map element. First of all, we need to explicitly give the app permission to use map capabilities. In order to do that navigate to Solution Explorer, Properties, WMAppManifest.xml, Capabilities and then check on the “ID_CAP_MAP” option. Now look at the following code and follow the comments in line.

private void button1_Click(object sender, RoutedEventArgs e)
{
    // set map to a longitude and latitude at zoom 10
    map1.SetView(new GeoCoordinate(23.723, 90.4086), 10);


// change to Road view
map1.CartographicMode =
MapCartographicMode.Road;
// to Ariel view map1.CartographicMode = MapCartographicMode.Aerial;
    ++map1.ZoomLevel;
}

private void map1_DoubleTap(object sender, GestureEventArgs e)
{
    var point = e.GetPosition(map1); // get position on the screen
    // translate screen position to geo location
var location = map1.ConvertViewportPointToGeoCoordinate(point);
    MessageBox.Show(string.Format(
"Double tapped Lat/Long: {0:0.000}/{1:0.000}",
location.Latitude, location.Longitude)); }

Accessing GPS

Now that we have learned how to use elements from codebehind, let us see how we can access Windows Phone sensors, among which Global Positioning System (GPS) data is particularly interesting. Again, to be able to use location capability, we will have to check on “ID_CAP_LOCATION.”

private readonly GeoCoordinateWatcher _GeoWatcher;
public MainPage()
{
    InitializeComponent();
    _GeoWatcher = new GeoCoordinateWatcher(GeoPositionAccuracy.Default);
    _GeoWatcher.Start();
}

private void button1_Click(object sender, RoutedEventArgs e) { var position = _GeoWatcher.Position; MessageBox.Show(string.Format(
"Current Lat/Long/Alt: {0:0.000}/{1:0.000}/{2:0.000}", position.Location.Latitude,
position.Location.Longitude,
position.Location.Altitude)); }

You need to use Additional tools available in the phone Emulator to enter some fake data and feed it to the app, so that you can simulate your app’s behavior in actual condition. We will take a stab at it in the Accelerometer section. A point to remember while programming with sensors is that they use device power and can drain it pretty quickly.

Accelerometer

Let us access 3D position data of the phone. We need a reference to Microsoft.Devices.Sensors:

Accelerometer accel;

private void button1_Click(object sender, RoutedEventArgs e)
{
    accel = new Accelerometer();
    accel.CurrentValueChanged += accel_CurrentValueChanged;

accel.Start(); }
void accel_CurrentValueChanged(object sender,
SensorReadingEventArgs<AccelerometerReading> e) { var reading = e.SensorReading.Acceleration;
// access reading.X, reading.Y,
// reading.Z, e.SensorReading.Timestamp
}


Feeding Fake Data

You can use Additional tools to capture screenshot of the app, which is important for submitting your app to the marketplace. You can feed fake map as well as accelerometer data.

image

Calling Delegates without Blocking UI Thread

Every UIElement (basically all elements are derived from this type eventually) has a Dispatcher property, which lets you invoke a delegate without blocking the UI thread from which it is being invoked:

void cell_Click(object sender, RoutedEventArgs e)
{
    Dispatcher.BeginInvoke(() => MessageBox.Show(gameResult));
}

ApplicationBar

Application Bar gives you extra commands to execute on the current view try adding the following code inside <phone:PhoneApplicationPage /> of MainPage.xaml:

<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="Item 1"/> <shell:ApplicationBarMenuItem Text="Item 2"/> </shell:ApplicationBar.MenuItems> </shell:ApplicationBar> </phone:PhoneApplicationPage.ApplicationBar>

The following is not the output of the above code, rather an example how a real app makes use of the feature:

image

Launchers and Choosers

There are classes that allow to prompt user for range of input types and use it in your app. Many of them also allow to use default phone tasks, such as SMS compose Photo chooser. The following example allows user to take photo which your app can directly use. In this case, we have rendered it in an Image element:

private CameraCaptureTask _CameraCaptureTask = new CameraCaptureTask();
public Page1()
{
    InitializeComponent();
    _CameraCaptureTask.Completed
         += _CameraCaptureTask_Completed;
}

private void ApplicationBarMenuItem_Click(object sender, EventArgs e)
{
    _CameraCaptureTask.Show();
}

void _CameraCaptureTask_Completed(object sender, PhotoResult e)
{
    if (e.TaskResult == TaskResult.OK)
    {
        var bmp = new BitmapImage();
        bmp.SetSource(e.ChosenPhoto);
        image1.Source = bmp;
    }
}

Another example, which opens phone’s default SMS compose screen with pre-filled values:

new SmsComposeTask { Body = "Hello, SMS!", To = "+880101010101" }.Show();

NavigationService

Your app will not live in a single page. It will obviously need multiple pages, so navigating around them is a very necessary aspect to address. Pages on Windows Phone work much like browser. When you click on Back after you have visited a link in a browser, it will take you to the originating page. Both browser and Windows Phone’s navigation system keep track of the visited links in a stack, and in both cases Back and Forward work the same way. Let us take a look how you can navigate from one page to another along with parameters:

NavigationService.Navigate(new Uri("/Forecast.xaml?City=" + city.Text, 
UriKind.Relative));

Now in the Forecast.xaml, see how it is being picked up:

protected override void OnNavigatedTo(NavigationEventArgs e)
{
    var city = this.NavigationContext.QueryString["City"];
}

 

Making a Web Request

You can use WebClient as well as WebRequest for this, but let us look at the latter, the more difficult one here:

private void MakeRequest()
{
    // initialize a new WebRequest
    var woeidRequest = (HttpWebRequest) WebRequest.Create(new Uri(url));

    // set up the state object for the async request
    var woeidState = new State {AsyncRequest = woeidRequest};

    // start the asynchronous request
    woeidRequest.BeginGetResponse(HandleWoeidResponse, woeidState);

// .... more code to follow } private void HandleWoeidResponse(IAsyncResult asyncResult) { // get the state information var woeidState = (State) asyncResult.AsyncState; var woeidRequest = woeidState.AsyncRequest; // end the async request woeidState.AsyncResponse = (HttpWebResponse)
woeidRequest.EndGetResponse(asyncResult);
try { // get the stream containing the response from the async call var state = woeidState.AsyncResponse.GetResponseStream(); var xmlState = XElement.Load(state); // .... more code to follow } }
public class State
{
    public HttpWebRequest AsyncRequest { get; set; }
    public HttpWebResponse AsyncResponse { get; set; }
}

IsolatedStorage

You can save files for your app. You can even serialize your objects to files and retrieve and deserialize when necessary. Let us see this very useful helper class for such operations:

internal sealed class StorageHelper
{
    public static void DeleteFile(string fileName)
    {
        using (var appStorage = IsolatedStorageFile.GetUserStoreForApplication())
        {
            appStorage.DeleteFile(fileName);
        }
    }

// Example: StorageHelper.Save("student.dat", student); public static void Save<T>(string fileName, T thing) { using (var appStorage = IsolatedStorageFile.GetUserStoreForApplication()) { using (var file = appStorage.OpenFile(fileName, FileMode.Create)) { using (var writer = new StreamWriter(file)) { var serializer = new XmlSerializer(typeof(T)); serializer.Serialize(writer, thing); writer.Close(); } file.Close(); } } }
// Example: var student = StorageHelper.Read<Student> ("student.dat"); public static T Read<T>(string fileName) where T : new() { T thing; using (var appStorage = IsolatedStorageFile.GetUserStoreForApplication()) { using (var stream = new IsolatedStorageFileStream(fileName,
FileMode.OpenOrCreate, FileAccess.Read, appStorage)) { using (var reader = new StreamReader(stream)) { var serializer = new XmlSerializer(typeof(T)); thing = reader.EndOfStream ?
new T() : (T)serializer.Deserialize(reader); reader.Close(); stream.Close(); } } }
return thing; } }

Related Links