Chapter 2. Getting Started

Where Is the Hello World app?

Rather than show you a simple Hello World app, which is good at teaching syntax but not much else, I’ll be building a practical app that can be used throughout the book. This allows me to progressively build on the examples and use the native features of Windows 8 in a complete system.

Note

All kidding aside, if you want a Hello World app, see the Getting Started Guide on the Windows Developer Center at http://msdn.microsoft.com/library/windows/apps/br211386.

Microsoft’s Bing, like many popular search engines, provides a service for retrieving its results. This service has recently been migrated to the Windows Azure Marketplace and is perfect for showing the power of Windows 8 apps. It allows me to communicate with a free online service and demonstrate how to search, share, update tiles, and much more with a vast collection of images.

I’ll create a simple version first that is a single page application with a textbox and a button to execute the search. When the user clicks the search button, the app loads the results from the web service, attaches them to a listbox, and displays the results (see Figure 2-1).

Bing Search App

Figure 2-1. Bing Search App

Before you start building the app, let me take a moment to describe the Bing Search API so you can become familiar with the results format.

Bing Search API

In the Preface, I outlined the steps to subscribe to the Bing Search API service on the Windows Azure Marketplace. Once you’ve subscribed for the service, you can explore the data in the API using the DataMarket service explorer. This tool is available from the Bing Search API service home page by clicking the Explore This Dataset link. Figure 2-2 shows a screenshot of the tool after searching for Trains.

Results from Bing image search for train using the DataMarket service explorer

Figure 2-2. Results from Bing image search for train using the DataMarket service explorer

This page provides you with five important pieces of information:

  • The available options for the Query

  • The resulting data format and fields

  • The Service root URL

  • The URL for current expressed query

  • The Primary Account Key associated to the logged in user

These items should be noted or recorded somewhere so you can refer to them throughout the remainder of the book.

In addition to providing a UI for exploring the service, the Windows Azure Marketplace provides code that can be used within your .NET application to access the data. If you navigate back to the Bing Search API landing page by clicking on the logo in the top left, you will see a link to download a .NET C# Class Library, which is a single .cs file that you can include in your application (see Figure 2-3).

Download .NET C# Class Library

Figure 2-3. Download .NET C# Class Library

The Bing Search API supports two formats at the moment. The first is an XML-based ATOM format, which will be used by the C# class that was just downloaded. In addition, the API supports a JSON format, which can easily be used by any HTML and JavaScript app. The documentation on the Windows Azure Marketplace contains more information about these formats, or you can put the URL for the current query into any web browser, providing your Primary Account Key as your username and password. This will return the results in their raw form.

Getting Started: The BingSimpleSearch App

If you’ve ever created a new project in Visual Studio, you already know how to get started creating Windows 8 apps. To begin, open Visual Studio 2012 on a Windows 8 machine, and select FileNewProject. Figure 2-4 shows the full list of templates available for Windows Windows 8 apps. Each language contains a similar list of templates for creating Windows 8 apps. Select Blank App (XAML) under the Visual C#Windows Store folder, enter the name BingSimpleSearch, and click OK.

New Project Dialog

Figure 2-4. New Project Dialog

Now that you have created a new project, open Solution Explorer (ViewSolution Explorer). You should see the files from Figure 2-5.

Solution Explorer for New Project

Figure 2-5. Solution Explorer for New Project

The empty application template for Windows 8 apps contains two XAML files. Both of these files contain an associated code-behind file (i.e., a file with the same name with the addition of .cs).

App.xaml

App.xaml is the application entry point for your project. This simple application just loads the MainPage. As an application evolves, this file can be used for initializing your application dependencies (e.g., an inversion of control container), handling tombstoning and saving of settings, and providing activation triggers.

MainPage.xaml

MainPage.xaml is the primary view for the application, and it contains no content by default. As an application evolves, this file would likely contain a Frame control (http://msdn.microsoft.com/en-US/library/windows/apps/windows.ui.xaml.controls.frame), which allows your app to provide navigation between multiple pages. It would also be used as the primary shell of the UI for your apps global items like settings.

Open up the MainPage.xaml file and you will see the initial XAML content provided by the template. This is where you will be adding the TextBox and the Button to perform your searching. Scroll down to the root grid (it should have a Background set to the ApplicationPageBackgroundBrush resource). Before you add the textbox and the button, you are going to layout the grid’s columns and rows as in Figure 2-6.

To do this, you need two rows and two columns. The two columns will be evenly spaced at 50% and 50%. The two rows, on the other hand, will be set up to provide only the minimum amount of space required for the textbox, and the remaining space will be allocated to the ListBox (as seen in Figure 2-6). The XAML for the grid layout definition would look like Example 2-1.

Example 2-1. Definition of Grid Layout

<Grid.RowDefinitions>
        <RowDefinition Height="Auto" />
        <RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
        <ColumnDefinition />
        <ColumnDefinition />
</Grid.ColumnDefinitions>
Sketch of Grid Layout

Figure 2-6. Sketch of Grid Layout

Immediately following the row and column definitions, add a TextBox and a Button like in Example 2-2.

Example 2-2. TextBox and Button for use with search app

<TextBox x:Name="SearchQuery" />
<Button Content="Search" Grid.Column="1" Click="Search_Click" />

Notice that you are providing a name to the textbox so that it can be accessed from the code-behind later. In addition, you need to supply the row and column assignments only if they are not equal to 0. The textbox is defaulted to Grid.Row="0" and Grid.Column="0". On the button there is a Click event assignment to Search_Click, which maps to a method called Search_Click on the code-behind where the Bing search code will be written (see Example 2-3). To access the code-behind, click the arrow next to MainPage.xaml in the Solution Explorer and open the file MainPage.xaml.cs.

Example 2-3. Search event on the code-behind for handling the Bing web service call

private async void Search_Click(object sender, RoutedEventArgs e)
{
        // Put webservice code here
}

Note

Communicating with a web service may take longer than 50ms. Because of that, WinRT requires that this be an asynchronous operation. In .NET, you can use the new async/await keywords. These new keywords allow you to write your asynchronous code as if it were synchronous and the compiler handles the transferring of data between different threads. You will notice later in Example 2-5, the await keyword is used to unwrap the Task<T> object from an async method. For example, if you have an asynchronous method that returns a Task<string>, calling that method with an await keyword will result in just a string. Despite the fact that the code in the example reads as a synchronous call, and debugs like one, under the covers it’s actually triggering a continuation in which case the method gets split into two: the code before the await and the code after the await. For more information about the new async and await keywords, see http://msdn.microsoft.com/en-us/library/windows/apps/hh452713.aspx.

Bing Search API Service class

In the previous section, I showed you the download link for the service classes provided by the Windows Azure Marketplace. Now that you’ve created your project you can add this file to your project.

In addition, you will need to add references to Microsoft.Data.OData.Metro and Microsoft.Data.Service.Client.Metro. To do so, you can right-click the References in the Solution Explorer and click Add Reference. From here, you can click the Browse button on the bottom, navigate to C:Program Files (x86)Microsoft WCF Data Services5.0inMetro, and select both Microsoft.Data.OData.Metro.dll and Microsoft.Data.Services.Client.Metro.dll. Finally, click OK.

This file, and the references, contain everything you need to connect from a .NET application. The only thing it’s missing is support for the latest asynchronous features in .NET 4.5. To add this, create a new class called BingSearchContainerExtensions.cs. Place the code from Example 2-4 into this new file.

Example 2-4. Async extensions for BingSearchContainer

using System.Collections.Generic;
using System.Data.Services.Client;
using System.Threading.Tasks;

namespace Bing
{
        public static class BingSearchContainerExtensions
        {
                public static Task<IEnumerable<T>> ExecuteAsync<T>(
                        this DataServiceQuery<T> query)
                {
                        return Task.Factory.FromAsync<IEnumerable<T>>(
                                query.BeginExecute, query.EndExecute, null);
                }
        }
}

Calling the Bing Search API

Now that the code is included and WCF Data Services are ready to communicate with our Windows Azure Marketplace endpoint the code is very straightforward. Example 2-5 shows the updated Search_Click method. In this method, I created a new BingSearchContainer with the Service root URL from the previous section, and provide my Primary Account key as the Credentials. From here, you can use one of the many methods provided by the download service file. In this case, you want images so you use the Image method and supply the necessary parameters. Finally, call the new async extension method, which executes the call to the web service and when it completes, you can update the UI with the resulting objects.

Example 2-5. WCF Data Services call to get search results

// add 'using Bing;'
// add 'using System.Net;'

private async void Search_Click(object sender, RoutedEventArgs e)
{
        string accountKey = "<AccountKey>";

        var context = new BingSearchContainer(
                new Uri("https://api.datamarket.azure.com/Data.ashx/Bing/Search"));
        context.Credentials = new NetworkCredential(accountKey, accountKey);

        var result = await context.Image(this.SearchQuery.Text,
                "en-US", null, null, null, null).ExecuteAsync();
        ImagesList.ItemsSource = result.ToList();
}

Wrapping Up the UI

The final piece is to bind the visual elements. In Example 2-5, you set the results to an ImagesList ListBox that had not been created yet. On the ListBox, you will need to specify a DataTemplate for how to visually represent the model, which in this case is just a single image. Example 2-6 shows the ListBox definition and should be placed in the MainPage.xaml file directly under the search button.

Example 2-6. ListBox with a DataTemplate for an image result

<ListBox x:Name="ImagesList" Margin="40" Grid.Row="1">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <StackPanel Orientation="Horizontal">
                <Image Source="{Binding Thumbnail.MediaUrl}" Width="100" />
                <TextBlock Text="{Binding Title}" />
            </StackPanel>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

We are also going to add two images mapped to the thumbnail and the full-size image on the right-hand column. This will give you the typical effect of an image appearing pixelated while loading and becoming sharper once the download of the full-size image completes. For this effect, stack the images on top of each other; since they are the same aspect ratio, it will show the thumbnail and then cover it up with the full-size image (see Example 2-7). Although the only requirement is that this code is at the same level as the other items in the Grid, I recommend placing this code below the ListBox.

Example 2-7. Large screen image bound to selected item of the ListBox

<Grid Grid.Row="1" Grid.Column="1">
    <Image Source="{Binding SelectedItem.Thumbnail.MediaUrl, ElementName=ImagesList}" />
    <Image Source="{Binding SelectedItem.MediaUrl, ElementName=ImagesList}" />
</Grid>

You may also notice the usage of the ElementName binding in Example 2-7. This is telling the app to access our model through the ListBox’s SelectedItem property.

Running the BingSimpleSearch App

Your patience is about to be rewarded. You can click Run (the play button) in Visual Studio and your app will build, deploy (install on your Windows 8 Start Screen), and launch. Now you can enter whatever search term you desire, and the ListBox will populate with the thumbnails. If you select one of the images, the full-size image will populate on the right-hand side of the screen, as shown in Figure 2-7.

Bing SimpleSearch in action

Figure 2-7. Bing SimpleSearch in action

This is a simple example that just creates a few controls, uses C# to access a web service, parses the results, and then displays that data to the user using a ListBox control. With the exception of the XAML controls, all of the code is written with the .NET Profile for Windows 8 Apps. What I’d really like to do is leverage the new features of WinRT, which are found under the Windows.* namespace.

Unlocking WinRT (the FileSavePicker)

This app allows access to full screen images that the user may want to download. With Windows 8 apps and WinRT there is no need to download the file in a web browser sense, because you can write directly to the filesystem by requesting a file using the new FileOpenPicker. Just like the search event handler, we need to add a button to allow the user to save the image. Replace the XAML for the Search Button from the earlier, with the code from Example 2-8.

Example 2-8. Save Button used to trigger the FileSavePicker

<StackPanel Grid.Column="1" Orientation="Horizontal">
        <Button Content="Search" Click="Search_Click" />
        <Button Content="Save" Click="Save_Click" />
        <TextBlock x:Name="Status" Style="{StaticResource BasicTextStyle}" />
</StackPanel>

Basically, I’ve taken the Search Button and wrapped it into a StackPanel so all the elements line up in a row. Then I added the new Save Button, which points to a new event handler in the code-behind. Finally, I added a new TextBlock to display a status when saving the image.

To wire up the code for the Save Button, I have to add the code in the code-behind. Example 2-9 shows the code needed to download the file when the Save Button is clicked.

Example 2-9. Event Handler for the Save Button

// add 'using System;'
// add 'using Windows.Networking.BackgroundTransfer;'
// add 'using Windows.Storage.Pickers;'

private async void Save_Click(object sender, RoutedEventArgs e)
{
        var image = ImagesList.SelectedItem as ImageResult;
        if (image == null) return;

        var uri = new Uri(image.MediaUrl);
        var filename = uri.Segments[uri.Segments.Length - 1];
        var extension = System.IO.Path.GetExtension(filename);

        var picker = new FileSavePicker();
        picker.SuggestedFileName = filename;
        picker.SuggestedStartLocation = PickerLocationId.PicturesLibrary;
        picker.FileTypeChoices.Add(extension.Trim('.').ToUpper(),
                        new string[] { extension });

        var saveFile = await picker.PickSaveFileAsync();
        if (saveFile != null)
        {
                Status.Text = "Download Started";
                var download = new BackgroundDownloader().CreateDownload(uri, saveFile);
                await download.StartAsync();
                Status.Text = "Download Complete";
        }
}

The event handler does two basic things that use the new WinRT APIs. First, it defines and displays the FileSavePicker for the user to select a file. Then it saves the file using the BackgroundDownloader API.

I could simply call the FileSavePicker with no arguments, but that would require the user to create the proper file extension without providing any hints to the user: not a very good user experience. On the other hand, I can take the filename from the URL and provide both the name and the extension as hints to the user. Before I created the FileSavePicker, I took a simple approach to parsing the filename and extensions from the URL. Now the FileSavePicker can be created and I can specify the suggested information. Call picker.PickSaveFileAsync(), which launches the FileSavePicker UI; the user is blocked until he selects a file or clicks cancel. In the event that the user cancels that UI, then the saveFile will be null; otherwise, I can take the file and write to it.

The second part of the event handler creates a new BackgroundDownloader and tells it to create a new DownloadOperation based on the URL and the file selected from the FileSavePicker. You can do a number of things with this DownloadOperation, like support larger files, support metered connections, and provide progress and cancellation support. In this case the images are fairly small, so just start the download and update the Status.Text property with a before and after status. For more information about the BackgroundDownload API, you can download a sample at http://code.msdn.microsoft.com/windowsapps/Background-Transfer-Sample-d7833f61.

If you run the app again, you will see a new button to save the image. If you perform a search, select an image, and click Save, you will see the FileSavePicker. The picker and the BackgroundDownloader are full WinRT APIs and are specific to this new platform. This is just a taste of some of the new APIs that are available.

Summary

If you’ve been following along, you’ve already created a nice simple app. So far we’ve created a new UI in XAML, used C# for communication over the network with a web service, and communicated with WinRT to provide direct file access based on the user’s selection. The next few chapters will expand on this information and show more examples of how to use WinRT in a number of different places.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.216.96.94