Develop Windows Store apps - Exam Ref 70-484: Essentials of Developing Windows Store Apps Using C# (2013)

Exam Ref 70-484: Essentials of Developing Windows Store Apps Using C# (2013)

Chapter 2. Develop Windows Store apps

One of the unique characteristics of a great Windows Store app is its capability to interact with other apps and Windows 8 through extensions and contracts. Extensions provide a way to extend or customize capabilities of Windows features within Windows Store apps. Contracts ensure that diverse apps present features, such as sharing an item through another app, using the same interface.

An extension enables an app to integrate with Windows and extend features provided by the operating system. Developers can extend features such as picking contacts and associating specific file types with specific criteria within their own app and potentially make their implementation available to other apps and Windows.

A contract implemented in an app indicates that it is prepared to interact with other apps without the need to know how they work. The contract is an agreement between multiple apps that defines the requirements they must implement to participate in the interaction. The Settings contract provides users with a clean, intuitive way to manage application settings. The Search contract enables users to search content within an app as well as content from other apps. You can let users of your app share content with another app or service through the Share Target contract, or your app can act as a target for sharing content from other apps.

Objectives in this chapter:

§ Objective 2.1: Access and display contacts

§ Objective 2.2: Design for charms and contracts

§ Objective 2.3: Implement search

§ Objective 2.4: Implement Share in an app

§ Objective 2.5: Manage app settings and preferences

Objective 2.1: Access and display contacts

Windows Store apps can use the contact picker to enable users to access their contacts to be able to share content from within the application. The Windows.ApplicationModel.Contacts namespace provides the options for selecting contacts through a Windows Store app. An app can pick contacts from one or more Windows Store apps by selecting the provider of contacts from a drop-down list.

Windows Store apps can act as contact providers by declaring the contact picker extension in the package manifest. These apps are available in the people picker drop-down menu when the user selects one or more contacts.

The ContactPicker class is used to set up the user interface (UI). The ContactPickerUI class, provided by the Windows.ApplicationModel.Contacts.Provider namespace, is used to display selected contacts. You can filter the contacts to be displayed in your application by specifying which fields from the contacts to use when selecting them. You can create new contacts and update their properties, such as their thumbnail, from within your app.

NOTE

This objective covers how to:

§ Call the ContactPicker class.

§ Filter which contacts to display.

§ Select specific contact data.

§ Display a set number of contacts.

§ Create and modify contact information.

Calling the ContactPicker class

In your Windows Store app, you can allow users to choose one or more contacts to share content or send a customized message. You can provide your users with the option of either selecting a single contact or multiple contacts at a time. Windows provides a standard UI through which users access their contacts, as shown in Figure 2-1.

A screenshot of the People app in Windows 8. The app displays contact names and photo placeholders in alphabetical order.

Figure 2-1. The People app as the contact picker

To incorporate the contact picker in a Windows Store app, create an instance of the ContactPicker class. Call the PickSingleContactAsync or PickMultipleContactsAsync method to select one or more contacts. PickSingleContactAsync returns a single contact; PickMultipleContactsAsyncreturns one or more contacts. After the user has selected the contact(s), process the information contained in the result. The information about a contact is stored in a ContactInformation object. Using the ContactPicker class with the PickSingleContactAsync method shows how to use theContactPicker class with the PickSingleContactAsync.

USING THE CONTACTPICKER CLASS WITH THE PICKSINGLECONTACTASYNC METHOD

private async void PickContacts_Click(object sender, RoutedEventArgs e)

{

var contactPicker = new Windows.ApplicationModel.Contacts.ContactPicker();

contactPicker.CommitButtonText = "Select a contact";

ContactInformation contact = await contactPicker.PickSingleContactAsync();

// You can allow the user to pick multiple contacts with the

// PickMultipleContactsAsync method. Each member of the returned list

// is a ContactInformation object. Example:

// IReadOnlyList<ContactInformation> contacts =

// await contactPicker.PickMultipleContactsAsync();

if (contact != null)

{

// Display the name of the contact

ContactNameTextBox.Text = contact.Name;

// Display the emails

if (contact.Emails.Count > 0)

{

StringBuilder sb = new StringBuilder();

foreach (IContactField field in contact.Emails)

{

sb.AppendFormat("{0} ({1}) \n", field.Value, field.Category);

}

EmailsTextBox.Text = sb.ToString();

}

// Display the contact's thumbnail

Windows.Storage.Streams.IRandomAccessStreamWithContentType stream =

await contact.GetThumbnailAsync();

if (stream != null && stream.Size > 0)

{

BitmapImage image = new BitmapImage();

image.SetSource(stream);

ContactThumbnailImage.Source = image;

}

else

{

ContactThumbnailImage.Source = null;

}

}

}

The code in Setting up filters and the data collection for search results works when your application occupies the entire screen. When the app is in the snapped state, it throws an exception. Before you invoke PickSingleContactAsync or PickMultipleContactsAsync, you must ensure that your app can show the picker by checking whether the app is unsnapped; if it is in a snapped state, it can be unsnapped to open the picker. Checking whether the app is unsnapped shows how to check the state of the app before invoking the method on the ContactPicker class.

CHECKING WHETHER THE APP IS UNSNAPPED

using Windows.UI.VIewManagement;

public sealed partial class AddUsersPage : Page

{

// This method ensures that the Contact Picker user interface is presented

// only when your application is not in snapped state.

private bool EnsureUnsnapped()

{

bool unsnapped = ((ApplicationView.Value != ApplicationViewState.Snapped) ||

ApplicationView.TryUnsnap());

return unsnapped;

}

private async void PickContacts_Click(object sender, RoutedEventArgs e)

{

// Before you call the PickSingleContactAsync or PickMultipleContactsAsync,

// use the above method like so:

if (this.EnsureUnsnapped())

{

// Run the ContactPicker code.

}

}

}

The ContactInformation class provides the QueryCustomFields method, with which you can obtain the value of a custom field stored in a contact. The ContactInformation class has the following properties that can be used in your app after retrieving the contact(s):

§ CustomFields. A read-only list of custom fields stored in the contact, in which each member in the list is an object of type ContactField.

§ Emails. A read-only list of emails stored in the contact, in which each member in the list is an object of type ContactField.

§ InstantMessages. A read-only list of instant messaging accounts stored in the contact, in which each member in the list is an object of type ContactInstantMessageField.

§ Locations. A read-only list of ContactLocationField objects stored in the contact. A ContactLocationField object contains information about the user’s location and address.

§ Name. The name of the contact (a string).

§ PhoneNumbers. A read-only list of phone numbers associated with the contact, in which each member in the list is an object of type ContactField.

The ContactField class used to represent members in a ContactInformation object consists of the following properties:

§ Category. The category specified by the ContactFieldCategory enumeration that the contact belongs to

§ Name. The name of the field

§ Type. The type of contact data specified by the ContactFieldType enumeration

§ Value. The value of the field

A ContactField object must contain a string value and a value for the Type property from the enumeration ContactFieldType, at a minimum. The Type property specifies whether the data in the ContactField object is a phone number, email address, location, or something else. Optionally, aContactField object can contain a value in the Category property to distinguish between home, work, mobile, or other data.

Filtering which contacts to display

In your Windows Store app, you might need the email addresses of the contacts your users select for a feature. When you invoke either the PickSingleContactAsync or the PickMultipleContactsAsync method of the ContactPicker class, the default behavior is to show the contact as a complete entity. You can set the SelectionMode property of the ContactPicker class to one of the values of the ContactSelectionMode enumeration. Table 2-1 describes the ContactSelectionMode enumeration members.

Table 2-1. ContactSelectionMode enumeration members

MEMBER

VALUE

DESCRIPTION

Contacts

0

Specifies that the user wants to select the entire contact. This is the default behavior.

Fields

1

Specifies that the user wants to select only certain fields.

To filter the contacts your app wants to display, you need to set the SelectionMode property to ContactSelectionMode.Fields and populate the DesiredFields array (property of the ContactPicker class) to members of the KnownContactField class. If you add only one field to the DesiredFieldsarray, a contact will be considered a match if it has that field. If you add multiple fields to the DesiredFields array, a contact is considered a match if it has any of the fields. The KnownContactField class has the following properties:

§ Email. Contains the name of the field used for email addresses

§ InstantMessage. Contains the name of the field used for instant messaging accounts

§ Location. Contains the name of the field used for the contact’s location

§ PhoneNumber. Contains the name of the field used for phone numbers

If your application requires the fields of a contact to be selected in order of preference, you should add them to the DesiredFields property in that order of preference. For example, if you want both the email addresses and phone numbers of the selected contacts, but prefer the phone numbers, put the PhoneNumber field before the Email field in the DesiredFields array, as shown in Using the DesiredFields property for order of preference.

USING THE DESIREDFIELDS PROPERTY FOR ORDER OF PREFERENCE

private async void PickContacts_Click(object sender, RoutedEventArgs e)

{

if (this.EnsureUnsnapped())

{

var ContactPicker = new Windows.ApplicationModel.Contacts.ContactPicker();

contactPicker.CommitButtonText = "Select a contact";

// Filter the contacts which have their email and phone numbers, with

// Email as the preference

contactPicker.SelectionMode = ContactSelectionMode.Fields;

contactPicker.DesiredFields.Add(KnownContactField.Email);

contactPicker.DesiredFields.Add(KnownContactField.PhoneNumber);

ContactInformation contact = await ContactPicker.PickSingleContactAsync();

If (contact != null)

{

// Display the name of the contact

ContactNameTextBox.Text = contact.Name;

// Display the emails

if (contact.Emails.Count > 0)

{

StringBuilder sb = new StringBuilder();

foreach (IContactField field in contact.Emails)

{

sb.AppendFormat({0} ({1}) \n", field.Value, field.Category);

}

emailsTextBlock.Text = sb.ToString();

}

}

}

}

Selecting specific contact data

The ContactInformation class contains information about a contact obtained from a call to the ContactPicker class. Properties of the ContactInformation class such as Emails and PhoneNumbers can contain more than one value in the collection.

In your app, you might be required to display the contact’s work phone number and email, specifically avoiding their home phone number and email for privacy reasons. To implement such a requirement, you should check the Type and Category properties of the ContactField object you need to evaluate.

The ContactFieldCategory enumeration defines the categories of data the ContactField class can belong to. You can use the value of this enumeration to show, hide, or highlight a particular category of data (for example, you can bold all work-related contact information). Table 2-2 describes the ContactFieldCategory enumeration members.

Table 2-2. ContactFieldCategory enumeration members

MEMBER

VALUE

DESCRIPTION

None

0

Data doesn’t belong to any category.

Home

1

Data belongs to the Home category.

Work

2

Data belongs to the Work category.

Mobile

3

Data belongs to the Mobile category.

Other

4

Data belongs to the Other category.

The ContactFieldType enumeration defines the type of contact data in the ContactField class. Your application can select to display only specific type(s) of contact data by checking the value of this field in the ContactField class. Table 2-3 describes the ContactFieldType enumeration members.

Table 2-3. ContactFieldType enumeration members

MEMBER

VALUE

DESCRIPTION

Email

0

The contact’s email address

PhoneNumber

1

The contact’s phone number

Location

2

The contact’s location

InstantMessage

3

The contact’s instant message user name

Custom

4

A custom value for the contact

Using Type and Category properties of ContactField to select data shows how to use the Type and Category properties of the ContactField object to select specific contact data.

USING TYPE AND CATEGORY PROPERTIES OF CONTACTFIELD TO SELECT DATA

private void DisplayContactInformation(TextBlock emailTextBlock,

TextBlock phoneTextBlock,

IReadOnlyCollection<ContactField> fields)

{

if (fields.Count > 0)

{

foreach (IContactField field in fields)

{

// Display the work email

if (field.Type == ContactFieldType.Email &&

field.Category == ContactFieldCategory.Work)

{

emailTextBlock.Text = field.Value;

}

// Display the work phone number

if (field.Type == ContactFieldType.PhoneNumber &&

field.Category == ContactFieldCategory.Work)

{

phoneTextBlock.Text = field.Value;

}

}

}

}

Displaying a set number of contacts

Your Windows Store app can act as a contact picker provider when it declares the contact picker extension in the list of declarations in the package manifest file, shown in Figure 2-2. An application that declares this extension is expected to provide a UI through which the user can select one or more contacts.

A screenshot of the Declarations tab in Visual Studio. The Contact Picker option is selected.

Figure 2-2. Contact picker extension declaration

When a Windows Store app provides the user with an option to select one or more contacts, an app that is registered with Windows as a contact information provider is launched as an app embedded within the Windows Store app. The user has the option to choose either your app or the People app in Windows as the contact picker source, as shown in Figure 2-3.

A screenshot of the People app showing two options in a drop-down list: 70-484 Contact Picker Sample and People.

Figure 2-3. Contact picker selection option

A Windows Store app that has declared the contact picker extension receives an OnActivated event with the activation kind set to ActivationKind.ContactPicker in the event arguments of the type Windows.ApplicationModel.Activation.IActivatedEventArgs. In the event handler, you can create an instance of the page that implements the UI of the contact picker, as shown in Using the OnActivated event handler.

USING THE ONACTIVATED EVENT HANDLER

using Windows.ApplicationModel.Activation;

public partial class App : Application

{

protected override void OnActivated(IActivatedEventArgs args)

{

// Check if we have been activated to acts as contact picker source

if (args.Kind == ActivationKind.ContactPicker)

{

// The ContactPickerPage has an Activate method. In this method, the

// the content of the current window is set to the page and the window

// is activated.

var page = new ContactPickerPage();

page.Activate((ContactPickerActivatedEventArgs)args);

}

else

{

base.OnActivated(args);

}

}

}

A Windows Store app that implements the contact picker extension has the capability to restrict the number of contacts that will be displayed and made available to the user for selection. The app can query remote web services or a local database for the list of contacts, and can filter the list of contacts even before the list is displayed.

Creating and modifying contact information

When a Windows Store app that declares the contact picker extension is activated by another Windows Store app, an instance of the ContactPickerUI class is available through the ContactPickerActivatedEventArgs event argument as a property. The ContactPickerUI object represents the section that lists the contacts when the user wants to select contacts. (See App 2 in Figure 2-4.) When the user selects one or more contacts from the list, the selected contacts are then passed back to the calling application as a list of ContactInformation objects.

A diagram showing the sequence of actions leading to the selection of one or more contacts from a Windows Store app. In the App 1 box, an arrow leads from the Pick Contact button to the App 2 box. The App 2 box has a Select button, and an arrow leads from the button to the App 1 box.

Figure 2-4. Windows Store app acting as a contact provider

A Windows Store app that is a provider of contacts should display a list of contacts to the user upon request. The user then selects one or more contacts from this list. The selected contacts are added to the ContactPickerUI object, as shown in Using the ContactPickerUI object.

USING THE CONTACTPICKERUI OBJECT

using Windows.ApplicationModel.Activation;

public void AddContact(TwitterContact twContact)

{

Windows.ApplicationModel.Contacts.Contact contact =

new Windows.ApplicationModel.Contacts.Contact();

contact.Name = twContact.Name;

// Add the email

if (string.IsNullOrEmpty(twContact.Email))

contact.Fields.Add(new ContactField(twContact.Email,

ContactFieldType.Email, ContactFieldCategory.Work));

// Add the phone number

if (string.IsNullOrEmpty(twContact.Phone))

contact.Fields.Add(new ContactField(twContact.Phone,

ContactFieldType.PhoneNumber, ContactFieldCategory.Work));

switch (contactPickerUI.AddContact(twContact.Id, contact))

{

case AddContactResult.Added:

Status.Text = twContact.Name + " was already added to the basket";

break;

case AddContactResult.AlreadyAdded:

Status.Text = twContact.Name + " is already added to the basket";

break;

case AddContactResult.Unavailable:

default:

Status.Text = twContact.Name + " could not be added to the basket";

break;

}

}

When the user clicks the Select button, one or more ContactInformation objects are returned to the app that invoked the contact picker. The user might decide to cancel the selection, in which case PickSingleContactAsync or PickMultipleContactsAsync returns null.

The ContactPickerUI class provides a highly flexible way to incorporate contact sources in Windows Store apps. Users have the option to change or edit the contact information before adding to the basket of choices they have made before finalizing their selection.

THOUGHT EXPERIMENT

Building a Windows Store app contacts manager

In this thought experiment, apply what you’ve learned about this objective. You can find answers to these questions in the “Answers” section at the end of this chapter.

Your manager has asked you to develop a Windows Store app that enables users to import contacts into the app from their preferred email provider as well from files that contain archived contact data.

One of the requirements of your app is to provide users with the ability to filter and select contacts during the import. In addition, your app is required to provide contacts to other Windows Store apps whenever required. The app should also provide the ability to filter contacts with specific fields.

Answer the following questions for your manager:

1. Will your application be capable of importing contacts from remote web sources and files exported by devices while acting as a contact provider at the same time?

2. How will you ensure the app works in all view states?

3. Will users be able to select as many contacts as they want from the imported list?

Objective summary

§ The ContactPicker class provides Windows Store apps with the capability to select one or more contacts.

§ You can set up the ContactPicker class to select contacts with values in specific fields, such as those with email addresses and phone numbers.

§ The type and category of data in a contact can be used to select the information to be displayed in the app.

§ A Windows Store app can implement the contact picker extension and act as a provider of contacts for other apps.

Objective review

Answer the following questions to test your knowledge of the information in this objective. You can find the answers to these questions and explanations of why each answer choice is correct or incorrect in the “Answers” section at the end of this chapter.

1. You have been asked to design a contact picker app. Which contact fields are available in the ContactInformation class? (Choose all that apply.)

a. Name

b. Designation

c. Organization Name

d. Work Address

e. Work Phone Number

2. You have been asked to implement an application in which the user can select one or more contacts. What code should you use to provide this option to the user?

a. while (true) { ContactPicker.PickSingleContactAsync(); }

b. IReadOnlyList<Contact> contacts = await ContactPicker.PickMultipleContactsAsync();

c. IReadOnlyList<ContactInformation> contacts = await contactPicker.PickMultipleContactsAsync();

d. IReadOnlyList<ContactInformation> contacts = contactPicker.PickMultipleContactsAsync();

3. You are asked to design an app that acts as a provider of contacts. The app must function on tablets, touch laptops, and PCs. Which requirement is valid?

a. There is no need to consider the form factor or application’s view state.

b. The app should see whether the app is unsnapped; if not, it should attempt to unsnap it.

c. The app will function only when it is in the snapped state.

d. The system checks for the application’s view state and carries layout changes accordingly.

Objective 2.2: Design for charms and contracts

Microsoft design style emphasizes the “content over chrome” principle, which minimizes distractions for the user. A well-designed app should provide the user with an easy way to perform actions to interact with the app. Actions that are less frequently used, such as search and share or changing the settings of the app, are placed in the charms bar.

Windows Store apps can integrate actions provided by the charms bar such as search, share, connect to devices for printing or streaming media, or display application settings. The UI presented through the charms bar is placed on top of the app, so any UI elements below it will be hidden.

The Search, Share Target, and Play To contracts are exposed in a Windows Store app through a declaration in the app’s manifest file and an implementation in the app. Each contract implemented in an app is available to the user through the respective charm, for example, if an app implements the Search contract, it is invoked in the app through the Search charm. Windows provides the Settings charm as a universally accessible entry point in context to your app for the user to update settings that affect the app as well as settings exposed by the system. A Windows Store app can implement the Settings contract and include settings the user can update while using the app.

NOTE

This objective covers how to:

§ Choose the appropriate charm based on app requirements.

§ Design your app in a charm- and contract-aware manner.

§ Configure the app manifest for correct permissions.

Choosing the appropriate charm based on app requirements

The charms bar appears when users swipe from the right side of the screen, when they hover the mouse on the top-right side of their monitor, or when they press the Windows+C keyboard shortcut. The charms bar with various charms is shown in Figure 2-5.

A screenshot of the Windows 8 charms bar on the right side of the screen, displayed over the People app. The charms bar displays the Search, Share, Start, Devices, and Settings charms.

Figure 2-5. Windows 8 charms bar (on the right side of the screen) showing the various charms

The contracts available through the charms bar enable your app to interact with others. Some charms, such as Search, drive users into your app from other apps or the system, while others provide entry points for common requirements such as application settings. The contracts you can integrate in your app through the charms bar are the following:

§ Search. The Search contract enables the user to search for anything within your app, search another app, or even search the entire PC. Your app can be activated if it participates in the Search contract and has results to show for the search term.

§ Share Target. The Share Target contract provides users with the content to share from within your app with another app to perform an action such as sending an email without leaving your app.

§ Devices. Wired and wireless devices connected to the PC can be accessed via the Devices contract. You can print content from your app to a printer, sync content with another device such a Windows Phone, or stream media to your TV.

§ Settings. The Settings charm is used to change common settings of the PC and for your app. While app settings differ with apps, PC settings are the same in every app. You can implement the Settings contract to manage your application’s settings through the Settings charm.

EXAM TIP

You should be familiar with the contracts and extensions available for Windows Store apps. You can read more about contracts and extensions at http://msdn.microsoft.com/en-gb/library/windows/apps/hh464906.aspx.

The Search contract enables users to search your app’s content through the Search charm from anywhere in the system. Users can search for content in your app through the Search charm if your app is running, as shown on the left in Figure 2-6. Otherwise, users can enter the search term and select your app from the list of apps in the Search pane, as shown on the right in Figure 2-6.

Two screenshots illustrating the Search charm. The image on the left is the Weather app, in which you can enter a city, for example, in the search box in the Search charm. In the image on the right, you can use the search box in the Search charm to search for apps in the system.

Figure 2-6. The Search charm can be used to search within an app when it is running, such as the Weather app on the left. It can also be used to search for apps in the system, shown on the right.

When a Windows Store app implements the Share Target contract, it can receive content from other apps through the Share charm. An app with content to share is the share source, whereas an app that can receive content is a share target. The user does not have to leave the app when they want to share content from the app. Your app prepares the data it shares in a specific format and provides it to the target app. Figure 2-7 shows content from the Weather app being shared with the Mail app.

A screenshot of the Weather app with the Mail app open on the right side. The Mail app has a To field for email addresses, and the message portion of the Mail app shows information from the Weather app.

Figure 2-7. Share charm being used to share content from the Weather app in an email with the Mail app

Users should be able to send content to devices they use every day and are connected to their Windows 8 PCs and tablets. These devices include printers in the network, external monitors or televisions and smartphones, and other devices that support the tap and send experience. For example, you might want to print search results from Bing using a printer connected to the PC or share with a smartphone using tap and send. Figure 2-8 shows such a scenario.

This screenshot shows the Devices charm with three devices: Fax#:3, Microsoft XPS Document Writer, and Second screen. The user can send content from Internet Explorer to those devices.

Figure 2-8. Devices charm being used to send content from a page in Internet Explorer to other devices

The Settings contract provides users with an easy, in-context access to your app’s settings as well as settings exposed by the system. The items that appear in the Settings charm for an app should affect the app only and should be used by the user only occasionally. For example, if the user needs to turn off or turn on automatic synchronization of feeds in an RSS reading, it should be included as a setting through the Settings charm. Figure 2-9 shows the Settings charms for some Windows 8 apps.

These three screenshots of the Settings charm shows the Bing, Maps, and Weather apps with the commands available for these apps, such as Search History, Feedback, Image Credits, and many more. The Settings charm also contains options along the bottom portion of the window that are found in all Windows Store apps: Internet access, Muted, Unavailable, Notifications, Power, and Keyboard.

Figure 2-9. Settings charms of some Windows 8 applications

The commands in the Settings charm of the app link to secondary flyouts that provide users with a way to change their preferences in the app, update their credentials, and so on. A flyout is similar to a dialog box, except that a flyout can be dismissed by clicking or tapping outside its surface. In some apps, commands in the Settings charm link to external web pages that outline the privacy statement for the application. The command launches the external web page in the default browser configured by the user. The bottom of the Settings charm contains options to configure and change PC settings. These options are present in the Settings charm whenever it is open.

Designing your app in a charm-aware and contract-aware manner

It is important to design your Windows Store app with consideration for the various charms and contracts available. A great app should appeal with a unique design and user experience.

Windows Store apps fall into a variety of categories, for example, news and general information, productivity, media, and so on. Some types of apps, such as productivity, require a deeper level of interaction with their users and provide more commands than other types of apps. In a productivity app, users create tasks and reminders, add and delete notes, import content, and so on. You can implement the Search contract so that users can easily locate items they have created with your app with the Search charm.

As mentioned previously, several types of apps share their content with other apps and sometimes act as share targets. Productivity apps are great examples of share targets. Users want to import content from other apps or websites into a productivity app without switching context between multiple apps. The Share Target contract and its implementation through the Share charm provide a good user experience in this regard. If your app shares data with other apps, it is important to support as many types of data as will be meaningful for users to share. This ensures your app is capable of sharing content with a broad set of Windows Store apps.

Today’s PCs and other Windows 8 devices have the ability to connect to printers, monitors, televisions, and smartphones, either wirelessly or with wires. Implementing the Devices charm in your app means it will be able to share content with a variety of devices seamlessly.

If your Windows Store app has a number of options and user preferences that are global to the app, implementing the Settings contract via the Settings charm provides an in-context entry point across multiple pages. You can implement one or more settings flyouts in your app and even deep-link a specific flyout from an app page.

Design guidelines for the Search charm

When you implement the Search contract in your app, users can search the content in your app from anywhere in the system using the Search charm. If your app is frequently used to carry out search, it makes your app more visible among the list of apps that support search through the Search charm. Therefore, you should rely on the Search charm instead of creating your own UI to search your app’s content.

If your app enables users to explore content through search, you should consider adding a search icon to your app’s UI. The Search charm can be programmatically opened by clicking the search icon, thereby keeping your app’s search experience consistent with that of Windows 8 and other apps.

If search is the primary way users interact with your app, consider adding a search box to your app’s canvas. This is useful if your app requires a custom layout and more details in the search result than those provided through the Search charm. Users will still use the Search charm to carry out search. Therefore, the user can have two separate search histories for your app—one that is attached to the search box in the app and the other attached to the Search charm. Adding a search box in your app means that the searches carried out using your in-app search box will not increase your app’s rank and visibility in the Search charm.

If you add a search box to your app’s UI, use the TrySetQueryText method of the SearchPane class to keep the search query string added through the search box in sync with the Search charm. If the user clears the text in the search box, the Search charm should also be cleared. If the user prefers to use the Search charm to enter their query while the search box is visible in the app, the search box should be disabled, as shown in the Bing example in Figure 2-10.

Two screenshots of the Bing app are shown. The top screenshot shows the search box is enabled; the bottom screen shot shows the search box is disabled and the Search pane is visible.

Figure 2-10. The Bing app uses a search box that is disabled when the Search charm is visible

If you decide to add a search box in your app, remember to place it in the UI so it is not hidden by the charms bar or a flyout. You should not place the search box in the app bar.

In Windows Store apps that are text-heavy, such as document viewers, consider incorporating a feature to enable users to search in the text. Such a feature usually provides a full-screen experience and helps users move through large bodies of text. You should not implement this feature through the Search charm. Instead, add it to the app bar, paired with other commands such as Replace, at a page level. You should add the Ctrl+F keyboard shortcut, which is the default Find feature for Windows.

When the user starts typing into the search box in the Search charm, search suggestions appear below the search box. These suggestions are supplied by the app that’s visible on the screen if it has implemented the Search contract. Search suggestions do not appear if the app has not implemented the Search contract. There are two types of search suggestions an app can provide:

§ Query suggestions. These are auto-completions of the user’s query text and suggest queries the user might want to search for. If the user clicks a query suggestion, the app displays the search results page for that query. Query suggestions are strings provided by the application.

§ Result recommendations. These are strong or exact matches to the user’s query that the user might want to view immediately. If the user clicks a result recommendation, the app displays the page with the results. Result suggestions are strings provided by the application.

Your app should provide result recommendations to direct the user to the details of a particular result without the requirement to navigate through a search results page. A result recommendation consists of a thumbnail image, a title or label, and a brief description. Separate multiple result recommendations using labeled separators to help users distinguish the results. A Windows Store app can provide a maximum of five suggestions, and each separator counts toward this limit. Figure 2-11 shows the search suggestions and result recommendations from the Store app.

A screenshot of the query suggestions and result recommendations from the Store app in Windows 8. The word “Word” is entered in the search box, and search results include Word 2010 Training, Word A Day, and others.

Figure 2-11. Query suggestions and result recommendation from the Store app in Windows 8

In a Windows Store app that supports the Search contract, search results should be presented in a separate page after the user has selected a query suggestion or a result recommendation or used their own search query. The search results should be presented such that each result has an image or thumbnail (if the data model provides one), title, and brief description of the item. In the search results, the query string should be displayed prominently.

IMPORTANT VISIBILITY OF SEARCH RESULTS

Because the charms bar will be open until the user clicks your app or touches a result item, you should ensure that important search results are not hidden by the charms bar.

If the query string for a search produces a large number of results, you can provide a set of filters and arrange results with their scope set to the various filters. When the user clicks or taps a filter, the Search charm closes. It is recommended that the number of results for each filter be indicated clearly in the respective view, and there should be a way to view all the search results in one page. You can highlight the user’s query string in each search result, which is called hit highlighting. Figure 2-12 shows the search results for file names that contain the word screenshot, with various filters applied. The results include the total number of results for each filter, the query string highlighted, and hit highlighting of the query string.

A screenshot of the Files app showing the results from a search with various filters and hit highlighting. Each filter is displayed with the total number of results for the filter.

Figure 2-12. Search results obtained with the Files app in Windows 8

A Windows Store app can be activated when the user carries out a search query through the Search charm because the user chooses an app to search with when entering the query string. When the app activates, the QueryText property of the SearchActivatedEventArgs (in theOnSearchActivated method) provides the string entered by the user. The string can be used to carry out the search in the app.

It is possible for an app to activate with an empty QueryText string. In such a case, show the app’s last-viewed page if the app is running or suspended. If the app isn’t running or suspended, and is activated with an empty QueryText string, display the landing page for search results. In order to support scenarios in which your app is activated with an empty QueryText string, save the state of your app before the app is suspended or closed by the user.

If the app is in the snapped state when it is activated by the user carrying our search using the Search charm, the app automatically unsnaps. Therefore, the app should adjust itself to be the main app on the screen. You can use the SizeChanged event to adjust the layout of the app’s search result page. Save the search results currently displayed in the app as well as the query string, in case the app is activated to search for that query again. If the search results are prone to change over time, you should refresh the search results after displaying the saved search results.

Design guidelines for the Share charm

In a Windows Store app that acts as a source of content to be shared, the typical user action is to swipe the side of the screen (or use the Windows+H keyboard shortcut); display the charm; press the Share charm; and, using the Share window, share content from within the app. The app provides the content, and the metadata is presented in the content preview. The app that is used to share content implements the Share Target contract.

One or more QuickLinks are shown under the Share heading in the Share charm. A QuickLink is a deep link that invokes the respective share target. An app displays QuickLinks and the applications linked through them if they are relevant to the content provided by the source application. When the target app reports the sharing operation has completed, it can return a QuickLink to be displayed in the share window. Figure 2-13 shows content being shared from an app with a list of QuickLinks in the Share charm as well as a list of apps that support the Share Target contract.

This screenshot of the Share charm displays QuickLinks and apps that support the Share Target contract. The QuickLinks are the author’s email addresses; the apps are Mail and People.

Figure 2-13. Share charm with QuickLinks

In some cases, a sharing operation can take a long time to complete. In such cases, the user can switch to another app and reopen the share window to check the progress of the sharing operation. Windows will display a message in a dialog box from the target app if the sharing operation fails.

If your app acts like a share source, you should consider including links to content available online instead of the content that has been downloaded and saved locally. Your app should not modify the selection made by the user; for example, it shouldn’t include a link to a web page if the user wants to share only a portion of the text from the web page. You should consider providing metadata to the shared content (such as a title and description) that conveys what the user is trying to share. Whenever possible, include a thumbnail of an image being shared or a link to a web page to provide a reference to the user.

The Share charm should always be invoked using the charms bar. Windows adds a default message indicating that sharing is not supported from an app. Users might want to share the same content with multiple apps; therefore, it is a good practice to preserve the content selected by the user for sharing.

When your app is selected as a share target, the UI shown to the user is a minimal version of the interface when your app is the only app that is visible on the screen. It is important for the app to present the essential features for sharing content similar to that of the app when it occupies the full screen. Your app should not dismiss the UI after the sharing operation is completed.

You should avoid complex interactions and application logic when implementing the share target UI. The target app should not wait for additional content to be downloaded while the Share UI is open; the download should be completed before the UI is displayed. If your app must download data or process content to be shared before the Share UI is displayed, a message informing the user that the sharing operation is underway is helpful. Place buttons that the user is likely to use through the Share UI on the right side of the Share charm, so they can be reached by the right thumb.Figure 2-14 shows the UI for a share target, the Mail app.

A screenshot showing the UI of the Mail app when used as the share target. A button appears on the right side of the Mail app for sharing.

Figure 2-14. UI of the Mail app when used as the share target. Note that buttons should be placed on the right edge of the Share charm.

By acting as a source of content, your application has the capability to share content with devices in its close proximity as enabled by tap and send. Many Windows 8 devices have Near Field Communication (NFC) support and are capable of using tap and send with other Windows 8 devices and Windows Phone devices.

Design guidelines for the Settings charm

The Settings charm provides a simple, universally accessible entry point to your application with a single swipe from the right edge of a touch device or through the Windows+I keyboard shortcut. Windows automatically adds a set of commands to the Settings pane. These are the app name and publisher, a Rate and Review command that opens the app’s page in the Windows Store, and a Permissions command if the app has any capabilities declared in the manifest. Your app can provide up to eight additional commands. Ideally, the maximum number of commands added in an app’s Settings charm should be limited to four. If your app attempts to add more than eight commands to the Settings charm, an exception occurs.

The commands your app adds in the Settings charm are available throughout the app; that is, the commands are available through the Settings charm in all pages of the app. If a page requires commands specific to the page, implement these commands as menu items in the app bar.

A command in the Settings charm of a Windows Store app can either link to a web page or invoke a secondary flyout panel with more specific settings controls. The Windows Store app certification requirements make it mandatory for apps that collect any kind of personal information to provide a privacy policy. This is typically included as a command in the Settings charm.

Secondary settings flyout panels are limited to two sizes: narrow (346 pixels) or wide (646 pixels). In your Windows Store app, all the secondary panes should be the same size. The permissions flyout is provided by Windows, and the items listed in the flyout are configured according to the capabilities declared in your applications’ manifest file.

It is recommended that your app should include account/profile management through the Settings charm because the user might want to update these settings from within any page in the app. When designing the settings flyout for a command, you should minimize the number of controls. Use simple controls such as toggle switches for on/off values, radio buttons for mutually exclusive items, list box controls for single/multiple value selection, and text input boxes wherever dynamic text input is required.

You should minimize vertical scrolling in a secondary flyout and avoid any hierarchy of settings. Place the controls in a secondary flyout in a single column and configure them so that any changes in the settings are committed instantaneously.

The Settings charm is a great location for engaging the user with your app and providing them with the option to communicate with you by providing feedback about your app, bug reports and submit feature requests. Figure 2-15 shows a feedback form included in the Weather app in Windows 8 through the settings flyout.

A screenshot of a feedback form included in the Weather app in Windows 8. The form includes a text box in which the user can type a comment explaining what he or she likes about the app. The user can also choose options from two drop-down lists: one for how often the app is used and the other for rating the app. The feedback form is accessible through the Settings charm as a command.

Figure 2-15. A feedback form included in the Weather app in Windows 8

A vertical scrollbar is automatically added by the Settings charm to the settings flyout if the content does not fit the space available vertically.

Configuring the app manifest for correct permissions

In your Windows Store app, you can consider implementing the Search contract and even add share target support. In both cases, you will need to declare these contracts in the app manifest so that the permissions required in your app are set up correctly. Note that you are not required to add the Share Target contract if your app acts as a share source only.

Visual Studio provides developers with the templates for implementing the Search contract and Share contract. When an app is created with one of these templates, Visual Studio adds the appropriate declaration to the app manifest. When you right-click your Windows Store project in Visual Studio and then click Add New Item, you are presented with the dialog box shown in Figure 2-16.

A screenshot of the Add New Item dialog box. Windows Store is selected in the Visual C# tree on the left. Several template names are displayed in the middle pane, with a callout box drawn around Search contract and Share Target Contract.

Figure 2-16. Visual Studio templates to add Share and Search contracts

Visual Studio adds a page that is shown when your app is chosen as the share target and code to override the OnShareTargetActivated method in the App.xaml.cs file. When your app acts as a share target, you are provided with the option to support multiple data formats such as text, uniform resource identifiers (URIs), bitmaps, Hypertext Markup Language (HTML), and/or file types such as .jpg and .docx. Your app is expected to support at least one data format or file type. The app manifest is where you configure the data formats and file types your app will support.

Visual Studio adds a search results page and code to override the OnSearchActivated method in the App.xaml.cs file. The method provides the text entered by the user through the QueryText property of the SearchActivatedEventArgs argument. You can show the search results page to the user using this method. Note that Windows Store apps can have only one instance of the declaration for Share and Search contracts.

In the Settings charm of your app, the system adds a command to display the permissions required by your app. Windows provides the Permissions flyout based on the capabilities declared in your application’s manifest. Some capabilities such as location can be controlled by the user through the Permissions flyout.

THOUGHT EXPERIMENT

Porting a legacy app to a Windows Store app

In this thought experiment, apply what you’ve learned about this objective. You can find answers to these questions in the “Answers” section at the end of this chapter.

You have been asked to port a legacy desktop application to a Windows Store app. You are expected to focus on the UI and use key features available for Windows Store developers.

You determine that the ported app will appeal to users if you incorporate features such as searching the app for data and formatting, sending content via email, and connecting to printers.

Briefly explain the three steps you must take to incorporate search, share, and the capability to print content from your ported app.

Objective summary

§ In your app’s design, consider using the Search, Share, Devices, and Settings charms to help users interact with your app.

§ You should provide query suggestions and result recommendation when you implement the Search contract and integrate it in your app through the Search charm.

§ The UI provided by your app while implementing the Share Target contract should be minimal and simple for the user to use. You should integrate the Share Target contract in your app through the Share charm.

§ The Settings charm provides an entry point for your application’s settings, permissions, privacy statement, user session management, and a command to rate and review your app in the Windows Store.

§ Contracts implemented in Windows Store apps must be declared in the app manifest; otherwise, exceptions will occur if the user tries to access the features implemented through the contract.

Objective review

Answer the following questions to test your knowledge of the information in this objective. You can find the answers to these questions and explanations of why each answer choice is correct or incorrect in the “Answers” section at the end of this chapter.

1. You are developing a Windows Store app and you have been asked to investigate the feasibility of supporting contracts in the app via the charms bar. Which Windows 8 contract features are applicable to your app? (Choose all that apply.)

a. The charms bar is available only in touch-based devices.

b. A Search contract can be used to search within a page that is currently visible.

c. The app will be available as a share target if the Share Target contract is implemented.

d. The Settings charm is available for all Windows Store apps to provide settings commands.

e. Query suggestions and result recommendations improve the usability of the application.

2. In a Windows Store app, you can use the Settings charm to provide a number of commands with their respective settings flyouts. Which commands should you implement in the Settings charm for your app? (Choose all that apply.)

a. Account/session management

b. Theme preferences

c. A shortcut to close the app

d. An option for the user to provide feedback on the app

e. An option to share content from within your app

3. You need to support app activation via search. Which event is invoked by the system in your app when it is activated?

a. OnWindowCreated

b. OnLaunched

c. OnSearchActivated

d. OnActivated

Objective 2.3: Implement search

While designing your Windows Store app, if you have planned to implement the Search contract, you should expose this feature via the Search charm. Adding the Search contract to your app through the Search charm enables the user to search within your app from anywhere within the system. Your app can provide search query suggestions and result suggestions while the user is searching through the Search charm.

When the user enters a search query string and selects your app from a list of apps that implement the Search contract, your app is activated by Windows if it is not running. The query string entered by the user is available through the OnSearchActivated method. You can implement a page in your app to display search results with a preview of each item. This page is shown whenever the OnSearchActivated method is invoked.

NOTE

This objective covers how to:

§ Provide and constrain search within an app.

§ Provide search result previews.

§ Provide search suggestions using the SearchPane class.

§ Implement activation from within search.

§ Search for and launch other apps.

Providing and constraining search within an app

Visual Studio makes it easy for developers to add the Search contract in their Windows Store apps. When you select the Search Contract template in Visual Studio, code is added to override the OnSearchActivated virtual method in the Application class in your Windows Store app, and the app manifest is updated with the correct permission, as shown in Figure 2-17.

Two screenshots are displayed. The top image shows the Add New Item dialog box with the Search Contract selected. The bottom image shows the correct permission (the Search declaration) added in the package manifest

Figure 2-17. The Search Contract template available in Visual Studio can be used to implement Search Contract in a Windows Store app, which adds the correct permission in the package manifest

In order to speed up the search process when the app is visible on screen, the QuerySubmitted event can be used instead of waiting for the OnSearchActivated method to be invoked by Windows. When the QuerySubmitted event is invoked, your app should respond by displaying the search results page and populating it with results using the query string available in the QueryText property of the SearchPaneQuerySubmittedEventArgs parameter for the event.

You should register an event handler for this event in the Application class, as shown in Registering an event handler in the Application class.

REGISTERING AN EVENT HANDLER IN THE APPLICATION CLASS

using Windows.Foundation;

using Windows.ApplicationModel;

using Windows.ApplicationModel.Activation;

using Windows.ApplicationModel.Search;

// Other namespaces removed for brevity

sealed partial class App : Application

{

protected override void OnWindowCreated(WindowCreatedEventArgs args)

{

SearchPane.GetForCurrentView().QuerySubmitted +=

OnQuerySubmitted;

}

// Event handler for the QuerySubmitted event

private void OnQuerySubmitted(object sender,

SearchPaneQuerySubmittedEventArgs args)

{

// Use the query string in args.QueryText to initiate the search and navigate

// to the Search results page

var previousContent = Window.Current.Content;

var frame = previousContent as Frame;

if (frame != null)

{

frame.Navigate(typeof(SearchResultsPage), args.QueryText);

Window.Current.Content = frame;

Window.Current.Activate();

}

}

}

The search results page added by Visual Studio contains a GridView control and a ListView control to display the results in various view states; these controls are arranged in a Grid control. You can modify the DataTemplate of these controls to lay out the results from the search query.

MORE INFO VIEW STATES AND CONTROLS

You will learn about view states, grids, the Grid and GridView controls, and the ListView control in Chapter 3.

The query string typed by the user is available in the app through the OnSearchActivated method or the QuerySubmitted event and is passed to the search results with the Navigate method. You must implement the search mechanism and create a list of user-selectable result categories. The search results page contains a Back button to let users navigate back to the page where they were before carrying out the search. Without writing any code in the SearchResultsPage class, the UI of the search results page is shown in Figure 2-18.

A screenshot of a Windows Store app showing the default view of the search results page. The Search pane appears on the right with the term “sour dough” entered in the search box. A “No results match your search” message appears in the main part of the page.

Figure 2-18. Default view of the search results page

When your app does not return any results in the search, the user can clear the query string, type a new string, and carry out the search again. The system raises a QueryChanged event whenever the user changes the search query, with the SearchQueryChangedEventArgs providing the query string in your app. To speed up the search process, you can register for this event and carry out the search whenever this event is raised. Registering an app for the QueryChanged event registers your app for the QueryChanged event and responds to the event.

REGISTERING AN APP FOR THE QUERYCHANGED EVENT

using Windows.Foundation;

using Windows.ApplicationModel;

using Windows.ApplicationModel.Activation;

using Windows.ApplicationModel.Search;

// Other namespaces removed for brevity

sealed partial class App : Application

{

protected override void OnWindowCreated(WindowCreatedEventArgs args)

{

SearchPane.GetForCurrentView().QuerySubmitted +=

OnQuerySubmitted;

SearchPane.GetForCurrentView().QueryChanged +=

OnQueryChanged;

}

// Event handler for the QuerySubmitted event

private void OnQuerySubmitted(object sender,

SearchPaneQuerySubmittedEventArgs args)

{

// Use the query string in args.QueryText to initiate the search and navigate

// to the Search results page

var previousContent = Window.Current.Content;

var frame = previousContent as Frame;

if (frame != null)

{

frame.Navigate(typeof(SearchResultsPage), args.QueryText);

Window.Current.Content = frame;

Window.Current.Activate();

}

}

// Event handler for the QueryChanged event

private void OnQueryChanged(object sender,

SearchPaneQueryChangedEventArgs args)

{

// Use the query string in args.QueryText to clear the search results page and

// carry out a new search

}

}

The Search charm, if visible, is dismissed whenever the user swipes or taps the search results screen or clicks an item. You might want users to be able to carry out search by opening the Search charm when they start typing on the keyboard. You can add the ability to access the Search charm from the keyboard in your app’s main page and the search results page. To implement this feature, turn on type to search in the OnNavigatedTo event in the page and turn it off in the OnNavigatedFrom event, as shown in the following code:

using Windows.UI.Xaml.Navigation;

using Windows.ApplicationModel.Search;

public sealed partial class SearchResultsPage : Page

{

// Turn on type to search.

protected override void OnNavigatedTo(NavigationEventArgs args)

{

SearchPane.GetForCurrentView().ShowOnKeyboardInput = true;

base.OnNavigatedTo(args);

}

// Turn off type to search

protected override void OnNavigatedFrom(NavigationEventArgs args)

{

SearchPane.GetForCurrentView().ShowOnKeyboardInput = false;

base.OnNavigatedFrom(args);

}

}

Providing search result previews

When you add support for the Search contract in your Windows Store app, Visual Studio adds the XAML for the controls that display the search results in the autogenerated search results page. The default data template of each item in the search results page is shown in Default data template of items in the search results page (defined in StandardStyles.xaml).

DEFAULT DATA TEMPLATE OF ITEMS IN THE SEARCH RESULTS PAGE

<!-- Grid-appropriate 300 by 70 pixel item template as seen in the SearchResultsPage -->

<DataTemplate x:Key="StandardSmallIcon300×70ItemTemplate">

<Grid Width="294" Margin="6">

<Grid.ColumnDefinitions>

<ColumnDefinition Width="Auto"/>

<ColumnDefinition Width="*"/>

</Grid.ColumnDefinitions>

<Border Background="{StaticResource

ListViewItemPlaceholderBackgroundThemeBrush}"

Margin="0,0,0,10" Width="40" Height="40">

<Image Source="{Binding Image}" Stretch="UniformToFill"/>

</Border>

<StackPanel Grid.Column="1" Margin="10,-10,0,0">

<TextBlock Text="{Binding Title}" Style="{StaticResource BodyTextStyle}"

TextWrapping="NoWrap"/>

<TextBlock Text="{Binding Subtitle}" Style="{StaticResource BodyTextStyle}"

Foreground="{StaticResource

ApplicationSecondaryForegroundThemeBrush}"

TextWrapping="NoWrap"/>

<TextBlock Text="{Binding Description}" Style="{StaticResource

BodyTextStyle}"

Foreground="{StaticResource

ApplicationSecondaryForegroundThemeBrush}"

TextWrapping="NoWrap"/>

</StackPanel>

</Grid>

</DataTemplate>

The search results page is designed for a specific data model. It expects you to define a class and represent each item of the user’s search result with this class. Such a class is shown in the following example:

sealed class SearchResultItem

{

public Uri Image { get; set; }

public string Title { get; set; }

public string Subtitle { get; set; }

public string Description { get; set; }

}

The LoadState method for your search results page is invoked with the search query string passed through navigation arguments in the OnSearchActivated method or the QuerySubmitted event. You should initialize the search, and query your web service or local data source within this event.

After you have the search results, cache them until the user carries out the search again. At that point, process the results to set up the filters and the data collection that binds with the data control in the page, as shown in Setting up filters and the data collection for search results.

SETTING UP FILTERS AND THE DATA COLLECTION FOR SEARCH RESULTS

// Populates the page with content passed during navigation.

protected override void LoadState(object navigationParameter,

Dictionary<string, object> pageState)

{

var queryString = navigationParameter as string;

List<SearchResultItem> SearchResultCollection = new List<SearchResultItem>();

// Carry out the search using your web service or local data source and populate

// the SearchResultCollection.

// Prepare filters based on the categories in the search result.

var filters = new List<Filter>();

filters.Add(new Filter("All", this.SearchResultCollection.Count, true)); // Default

filters.Add(new Filter("Recipes", this.SearchResultCollection. Count(item =>

item.Category = "Recipes"), false));

filters.Add(new Filter("Items", this.SearchResultCollection. Count(item =>

item.Category = "Items"), false));

this.DefaultViewModel["QueryText"] = '\u201c' + queryString + '\u201c';

this.DefaultViewModel["Filters"] = filters;

this.DefaultViewModel["ShowFilters"] = filters.Count > 1;

// Prepare the results for the "All" filter

this.DefaultViewModel["Results"] = this.SearchResultCollection.Select(item =>

new SearchResultItem {

Image = item.ImageUri,

Title = item.Title,

Subtitle = item.Subtitle,

Description = item.Description

}).ToList();

}

The result of a search carried out with a Windows Store app is shown in Figure 2-19.

A screenshot of a Windows Store app with search results displayed, along with a preview of search result items.

Figure 2-19. Search results in a Windows Store app with previews of search result items

When you provide a preview for each search result item along with a filter that the user can choose to view a subset of all the items displayed, it is easier for the user to browse through the search results.

Providing search suggestions using the SearchPane class

When your app is used to search for content, Windows automatically provides a history of the user’s recent searches. You can enhance the user experience by providing query suggestions and result suggestions in your app. You might decide to support only one of them based on your app’s requirements and design decisions. Your app can obtain search suggestions from a variety of sources, such as:

§ From a remote web service, a local database, or a static list in the app

§ From a uniform resource locator (URL) that supports suggestions in the OpenSearch format

§ From a URL that supports suggestions in the XML search suggestions format

MORE INFO OPENSEARCH FORMAT AND XML SEARCH SUGGESTIONS

You can learn about the OpenSearch format specification at http://www.opensearch.org/Specifications/OpenSearch/Extensions/Suggestions. The XML search suggestions specification is available at http://msdn.microsoft.com/library/cc891508.aspx.

Your app can provide search suggestions as the user types in the search box in an event handler of the SuggestionsRequested event provided by the SearchPane class. This event is fired multiple times as the user types the search query string. A maximum of five search suggestions are shown in the Search charm even if your app adds more suggestions to the list. In the event handler, you should check for a match of the query string with data in your app, as shown in Checking for a match between the query string and app data.

CHECKING FOR A MATCH BETWEEN THE QUERY STRING AND APP DATA

using Windows.Foundation;

using Windows.ApplicationModel;

using Windows.ApplicationModel.Activation;

using Windows.ApplicationModel.Search;

// Other namespaces removed for brevity

sealed partial class App : Application

{

// Override the OnWindowCreated event to register the QuerySubmitted and

// QueryChanged event handlers at window creation time. This registration

// happens only once so that the app can receive user queries at any time.

protected override void OnWindowCreated(WindowCreatedEventArgs args)

{

SearchPane.GetForCurrentView().QuerySubmitted +=

OnQuerySubmitted;

SearchPane.GetForCurrentView().QueryChanged +=

OnQueryChanged;

// Subscribe to SuggestionsRequested event to provide suggestions

SearchPane.GetForCurrentView().SuggestionsRequested +=

OnSuggestionsRequested;

}

// Event handler for the SuggestionsRequested event

private void OnSuggestionsRequested(object sender,

SearchPaneSuggestionsRequestedEventArgs args)

{

// Use the query string in args.QueryText to look up a remote web service

// or a database.

if (!string.IsNullOrEmpty(args.QueryText))

{

List<string> suggestions = QueryDatabaseForSuggestions(args.QueryText);

foreach (string suggestion in suggestions)

{

// Note: Only a maximum of five items are shown.

args.Request.SearchSuggestionCollection.AppendQuerySuggestion(

suggestion);

}

}

}

}

Figure 2-20 shows the search suggestions from a Windows Store app as the user starts typing a search query.

A screenshot of the Search pane in a Windows Store app. The text “su” is entered into the search box. Search suggestions, such as “Sugar coated strawberries” and “Sugar candy” appear below the search box.

Figure 2-20. Search pane with search suggestions from a Windows Store app

In a Windows Store app that provides search suggestions, by default the Search pane will add the user’s previous searches and include them in the suggestions as well. The SuggestionsRequested event places search queries from previous searches in the Search pane at a higher priority than the suggestions provided by your app. You can turn off this behavior by setting SearchPane’s SearchHistoryEnabled property to False when you set up the event handler for the SuggestionsRequested event (within the OnWindowCreated method override in the Application class).

You can add one or more recommendations in the search suggestions based on the query string entered by the user. You might want to add a separator with a headline indicating this. Note that the maximum of five items in the list of search suggestions rule still applies. Therefore, a separator counts as one item in the list.

To provide result recommendations within your search suggestions, you should use the AppendSearchSeparator and AppendResultSuggestion methods of the SearchSuggestionCollection member in the SearchPaneSuggestionsRequestedEventArgs argument of the SuggestionsRequested event. You can add a thumbnail for the recommendation (an image sized 40 × 40) as an IRandomAccessStreamReference. The AppendResultSuggestion method accepts a tag in the third parameter for the result recommendation. The tag is useful for identifying the recommendation when the recommendation is selected by the user in the Search charm. Adding a recommendation to a list of results shows how a result recommendation is added to the list of results.

ADDING A RECOMMENDATION TO A LIST OF RESULTS

// Event handler for the SuggestionsRequested event

private void OnSuggestionsRequested(object sender,

SearchPaneSuggestionsRequestedEventArgs args)

{

// Use the query string in args.QueryText to look up a remote web service

// or a database.

if (!string.IsNullOrEmpty(args.QueryText))

{

List<string> suggestions = QueryDatabaseForSuggestions(args.QueryText);

foreach (string suggestion in suggestions)

{

args.Request.SearchSuggestionCollection.AppendQuerySuggestion(

suggestion);

}

if (args.QueryText.ToLower().Contains("sugar"))

{

IRandomAccessStreamReference thumbnail =

RandomAccessStreamReference.CreateFromUri(new

Uri("http://contoso.com/sberries.jpg"));

args.Request.SearchSuggestionCollection.AppendSearchSeparator(

"Recommended for you");

// "sugar-berry" is the tag

args.Request.SearchSuggestionCollection.AppendResultSuggestion("Sugar coated

strawberries", "Sugar coated strawberries are great for afternoon tea",

"sugar-berry",

thumbnail, "Sugar coated strawberries");

}

}

}

Figure 2-21 shows the Search pane for a Windows Store app with a result recommendation for the user.

A screenshot of the Search pane with search suggestions and a recommendation for the user from a Windows Store app. The word “sugar” is entered into the search box. The search suggestions below the search box include “Sugar cubes,” “Sugar pack 1Kg,” and Sugar Jelly.” A separator line appears, followed by “Sugar coated strawberries” and “Sugar coated strawberries ar …”

Figure 2-21. Search pane with search suggestions and a recommendation for the user from a Windows Store app

When the user selects one of the suggested results provided by your app and displayed in the Search pane, the system raises the ResultSuggestionChosen event. The result suggestion’s tag is provided with this event and it can be used to highlight the search query string in the result. You should set up your Windows Store app with an event handler for the ResultSuggestionChosen event, as shown in Creating an event handler for the ResultSuggestionChosen event.

CREATING AN EVENT HANDLER FOR THE RESULTSUGGESTIONCHOSEN EVENT

using Windows.Foundation;

using Windows.ApplicationModel;

using Windows.ApplicationModel.Activation;

using Windows.ApplicationModel.Search;

// Other namespaces removed for brevity

sealed partial class App : Application

{

// Override the OnWindowCreated event to register the QuerySubmitted &

// QueryChanged event handlers at window creation time. This registration

// happens only once so that the app can receive user queries at any time.

protected override void OnWindowCreated(WindowCreatedEventArgs args)

{

SearchPane.GetForCurrentView().QuerySubmitted +=

OnQuerySubmitted;

SearchPane.GetForCurrentView().QueryChanged +=

OnQueryChanged;

// Subscribe to SuggestionsRequested event to provide suggestions from

// your app.

SearchPane.GetForCurrentView().SuggestionsRequested +=

OnSuggestionsRequested;

// Subscribe to ResultSuggestionChosen event to highlight the selected item.

SearchPane.GetForCurrentView().ResultSuggestionChosen +=

OnResultSuggestionChosen;

}

// Event handler for the ResultSuggestionChosen event

private void OnResultSuggestionChosen(object sender,

SearchPaneResultSuggestionChosenEventArgs args)

{

// Use the tag in the event argument to highlight a result.

}

}

In some Windows Store apps, you might decide to provide suggestions based on local files present in the system. You can invoke the SetLocalContentSuggestionSettings method of the SearchPane class with an instance of the LocalContentSuggestionSettings class to specify the locations of files that are used to provide suggestions and a list of file properties to use. Note that your app must declare the relevant folder access capabilities in the app manifest to access those files. You can use the PropertiesToMatch property of the LocalContentSuggestionSettings class to specify a list of file properties used to provide the suggestions. If the list is empty, all the file properties that are available are used for suggestions. The AqsFilter property can be used to specify an Advanced Query Syntax (AQS) string to limit the types and kinds of files that are included in the suggestions. The following code shows how to set up the LocalContentSuggestionSettings class to provide photo suggestions from the Pictures library:

using Windows.ApplicationModel.Search;

using Windows.Storage;

using Windows.UI.Xaml.Navigation;

sealed partial class App : Application

{

protected override void OnWindowCreated(WindowCreatedEventArgs args)

{

var settings = new LocalContentSuggestionSettings();

settings.Enabled = true; // You have to set this explicitly

settings.Locations.Add(KnownFolders.PicturesLibrary);

settings.AqsFilter = "kind:pics";

SearchPane.GetForCurrentView().SetLocalContentSuggestionSettings(settings);

}

}

Implementing activation from within search

When a user opens the Search charm, a list of apps appears that can be selected to perform the search. If your app is not visible in the screen and is selected by the user in the Search charm to carry out the search, it is activated and is visible in the screen. The OnSearchActivated method or theQuerySubmitted event is invoked in your app with the search query provided in the QueryText property of the event argument. Visual Studio adds the OnSearchActivated method when you use the Search contract template, as shown in Overriding the OnSearchActivated method.

OVERRIDING THE ONSEARCHACTIVATED METHOD

protected async override void OnSearchActivated(SearchActivatedEventArgs args)

{

var previousContent = Window.Current.Content;

var frame = previousContent as Frame;

if (frame == null)

{

frame = new Frame();

SuspensionManager.RegisterFrame(frame, "AppFrame");

if (args.PreviousExecutionState == ApplicationExecutionState.Terminated)

{

try

{

await SuspensionManager.RestoreAsync();

}

catch (SuspensionManagerException)

{

// Error restoring state, continue.

}

}

}

frame.Navigate(typeof(SearchResultsPage), args.QueryText);

Window.Current.Content = frame;

Window.Current.Activate();

}

If your app is restored from a suspended state or if it is started anew, you might want to check the PreviousExecutionState and perform initialization before proceeding with the search. In some cases, simply showing an extended splash screen provides a good user experience.

EXAM TIP

You are not expected to remember all the events and methods required to implement the Search contract for the exam. However, it is important for you to know the way search works in a Windows Store app.

Searching for and launching other apps

In a Windows Store app, you can provide the user with the option to search for content within the app and include local content such as files of specific types in the search results. Your app might be capable of opening these files for the user or it might launch another app that supports the file type or a URI scheme association.

A Windows Store app can launch another app with the Launcher class (in the Windows.System namespace) using either of two methods:

§ LaunchFileAsync. Starts the default app associated with the specified file, optionally including the specified LauncherOptions.

§ LaunchUriAsync. Starts the default app associated with the URI scheme name for the specified URI, optionally including the specified LauncherOptions.

The LauncherOptions class specifies the options used to launch the default app for the file or URI. It has the following properties:

§ ContentType. Gets or sets the content type associated with the URI of a file on the network.

§ DisplayApplicationPicker. Gets or sets a value for a flag that indicates whether the Open With dialog box should be shown.

§ FallbackUri. Gets or sets a value of a URI that the browser should open if there is no app to handle the file type or URI.

§ PreferredApplicationDisplayName. Gets or sets a value of the display name of the app in the Windows Store that the user should install if there is no app to handle the file type or URI.

§ PreferredApplicationPackageFamilyName. Gets or sets a value of the package family name of the app in the Windows Store that the user should install if there is no app to handle the file type or URI.

USING APPROPRIATE PROPERTIES

The PreferredApplicationDisplayName and PreferredApplicationPackageFamilyName properties should be used together.

§ TreatAsUntrusted. Get or sets a value for a flag that indicates if the system should display a warning that the file or URI is potentially unsafe when starting the app with the file or URI.

§ UI. Gets the UI options when starting a default app. The value of this property is a LauncherUIOptions object. The object contains details such as the position of the UI element associated with the app that was launched.

THOUGHT EXPERIMENT

Building a search-friendly Windows Store app

In this thought experiment, apply what you’ve learned about this objective. You can find answers to these questions in the “Answers” section at the end of this chapter.

Your Windows Store app has received feedback from users asking you to include the capability to search content in your app. You have investigated the feasibilty of supporting search in your app.

What are the four steps you should take to support search in your app?

Objective summary

§ You should use the QuerySubmitted and QueryChanged events to implement search in your Windows Store app when it is visible on the screen.

§ You should provide a preview of the items listed in your app’s search result page. Users can browse the details of a result by looking at the preview of the item.

§ Search suggestions and result recommendations enhance the user experience of a Windows Store app. Whenever required, you can turn off the search history of the user for your app.

§ You should ensure that your app is activated when the user selects it after entering a search string.

§ If your app includes local files in the search results, you should ensure your app can launch Windows Store apps that can open these files.

Objective review

Answer the following questions to test your knowledge of the information in this objective. You can find the answers to these questions and explanations of why each answer choice is correct or incorrect in the “Answers” section at the end of this chapter.

1. You are preparing to implement the Search contract in your app. Which event handlers should you consider implementing in your app to provide a rich user experience? (Choose all that apply.)

a. The QuerySubmitted event, which fires when the user submits a search query

b. The QueryChanged event, which fires when the user changes a search query

c. The Loaded event of the Page class. which fires when the search results page is loaded

d. The OnSearchActivated event, which fires when the app is activated through search

e. The Unloaded event of the You can use the SearchPane class to provide search suggestions to your app’s users. Which event should you handle to provide search suggestions?

f. QueryChanged

g. SuggestionsRequested

h. ResultSuggestionChosen

i. QuerySubmitted

2. When your app provides result suggestions to the user performing a search, which event is fired to indicate that a suggested result has been selected by the user?

a. ResultSuggestionChosen

b. QuerySubmitted

c. QueryChanged

d. SuggestionsRequested

Objective 2.4: Implement Share in an app

Windows Store apps can share data with other apps in a variety of ways. Applications with a lot of text can use the Clipboard for copying and pasting content. Other apps can share content by saving it in a file and providing a save location and real-time file updates to other apps through the File Open Picker contract, File Save Picker contract, and Cached File Updater contract. The Share Target contract in Windows Store apps provides a simple, in-context, and universal experience to users interested in sharing content.

A Windows Store app can share data with other apps with the DataTransferManager class. A DataTransferManager object is available in every page that provides content to be shared with others apps. The content shared by an app can be limited by using the DataPackage object. An app can implement the Share Target contract and be activated through the OnShareTargetActivated event when another app selects it for sharing content.

NOTE

This objective covers how to:

§ Use the DataTransferManager class to share data with other apps.

§ Limit the scope of sharing using the DataPackage object.

§ Accept sharing requests by implementing activation from within Share.

§ Implement in-app share outside of the Share charm.

Using the DataTransferManager class to share data with other apps

If your Windows Store app contains data that can be shared with other apps, your app can be a share source without implementing a contract or configuring anything in the app manifest. By acting as a share source, your app can share rich, meaningful content such as thumbnails and images, rich text, files, and custom data. It also enables your app to decide the content that should be shared, unlike the use of the Clipboard, in which the user explicitly selects and copies data.

The Windows.ApplicationModel.DataTransfer namespace provides a number of classes for a Windows Store app to exchange data between a source app and a target app. These classes are used in share and Clipboard copy/paste operations.

To act as a share source, your app needs to implement an event handler for the DataRequested event, usually in the OnNavigatedTo event in a page, as shown in Implementing an event handler for the DataRequested event.

IMPLEMENTING AN EVENT HANDLER FOR THE DATAREQUESTED EVENT

// Register the current page as a share source

protected override void OnNavigatedTo(NavigationEventArgs args)

{

DataTransferManager dtManager = DataTransferManager.GetForCurrentView();

dtManager.DataRequested += OnDataRequested;

}

// Unregister the current page as a share source

protected override void OnNavigatedFromNavigationEventArgs args)

{

DataTransferManager dtManager = DataTransferManager.GetForCurrentView();

dtManager.DataRequested -= OnDataRequested;

}

// Event handler for the DataRequested event

private void OnDataRequested(DataTransferManager sender, DataRequestedEventArgs args)

{

DataRequest request = args.Request;

request.Data.Properties.Title = "70-484 Share text example";

request.Data.Properties.Description = "A demo of how a Windows Store app can

act as share source";

request.Data.SetText("Hello Exam 70-484!");

}

Figure 2-22 shows the Share pane when a Windows Store app shares content from within a page.

A screenshot showing a list of apps available for sharing content from a Windows Store app. After an app is selected for sharing content, the Share pane of the target app is populated with content from the source app.

Figure 2-22. Share charm with a list of apps available for sharing content and the Share pane with content shared by a Windows Store app

It is the responsibility of the target app to use the data shared by your Windows Store app. The target app might not be able to read all the data in the Properties object set by the source app. When the Share charm is invoked, two properties you set through the DataRequest object are shown in the Share pane: Title and Description. You should ensure that, in the source app, the actual data to be shared is specified in all the formats supported by the app, such as plain text, HTML, URI, RTF, IStorageItem (when sharing a binary file), image, or custom. (Figure 2-25, later in this chapter, shows the formats.) If your app provides data in multiple formats, there is a greater chance of the shared data to work with more Windows Store apps. The target app might prefer to use a specific type of content in the DataRequest object. For example, if HTML content and plain text content are both available in the DataRequest object, the Mail app will use the HTML content instead of the text content.

You should note that the target app cannot process arbitrary HTML content from your Windows Store app. You should use the CreateHtmlFormat method in the HtmlFormatHelper class (in the Windows.ApplicationModel.DataTransfer namespace) to prepare HTML content, as shown in the following code:

// Event handler for the DataRequested event

private void OnDataRequested(DataTransferManager sender, DataRequestedEventArgs args)

{

DataRequest request = args.Request;

request.Data.Properties.Title = "70-484 Share text example";

request.Data.Properties.Description = "A demo of how a Windows Store app can

act as share source";

request.Data.SetText("Hello Exam 70-484!");

request.Data.SetHtmlFormat(HtmlFormatHelper.CreateHtmlFormat("

<i>Exam 70-484 </i><b>rocks!</b>"));

}

A Windows Store app can contain a number of pages from which the user will share content. To facilitate sharing, you need to subscribe/unsubscribe for the DataRequested event and implement the event handler that packages the data in the DataRequest object. It is a good practice to implement the subscribe/unsubscribe code in an abstract base class and provide the implementation of the event handler in the pages from which the user will share content. Such an abstract class is shown in Using an abstract base class for sharing tasks.

USING AN ABSTRACT BASE CLASS FOR SHARING TASKS

// Namespace usings removed for brevity. LayoutAwarePage is a class that derives from

// the Page class. It adds a number of features to the Page class, you will learn about

// these features in the next objective.

public abstract class SharePageBase : LayoutAwarePage

{

private DataTransferManager dataTransferManager;

protected override void OnNavigatedTo(NavigationEventArgs args)

{

this.dataTransferManager = DataTransferManager.GetForCurrentView();

this.dataTransferManager.DataRequested += OnDataRequested;

}

protected override void OnNavigatedFrom(NavigationEventArgs args)

{

this.dataTransferManager = DataTransferManager.GetForCurrentView();

this.dataTransferManager.DataRequested -= OnDataRequested;

}

private void OnDataRequested(DataTransferManager sender,

DataRequestedEventArgs args)

{

SetupShareContent(args.Request);

}

// This method is implemented by each page that acts as a share source.

public abstract void SetupShareContent(DataRequest request);

}

When the user chooses a target for sharing the data from a source app, the system fires a TargetApplicationChosen event in the DataTransferManager class. You can use this event in your Windows Store app to record information about the target app used for sharing the content from your app. You can use this event to log and record the apps used by the user to share the content, thereby improving the user experience in future releases of your app.

In some cases, a Windows Store app can fail to share data with a target app. You can handle such situations using the FailWithDisplayText method available in the DataRequest object in the OnDataRequested event handler to display a text message to the user if anything goes wrong when your app is sharing content.

Accepting sharing requests by implementing activation within the Share charm

A Windows Store app can act both as a share source and share target. In the latter case, it must implement the Share Target contract. This contract sets up your Windows Store app to be presented as an option when the user invokes the Share charm, and the data shared from the source app is supported by your app. Your app has the option to support a definite number of formats, and you should register for only the formats your app can handle.

If you want your app to receive content shared by other apps, you should configure your app’s manifest file to indicate that it supports the Share Target contract. This step ensures that Windows includes your app as an option when the user invokes the Share charm when data formats supported by your app are shared. Windows shows only those target apps that support the data format used for sharing the content.

In a Windows Store app that acts as a share target, most of the work during a share operation is handled by the ShareOperation class in the Windows.ApplicationModel.DataTransfer.ShareTarget namespace. In addition, the QuickLink class is used to represent shortcuts that help users share content with apps they use most. Your app can optionally return a QuickLink created after the sharing operation is completed. The QuickLink then appears in a list whenever the Share charm is opened for sharing content. QuickLinks make it easier and simpler for users to frequently share content with the same person or group.

Visual Studio provides developers with a template for adding the Share Target contract in a Windows Store app. When you click the Add|New Item menu option in your Visual Studio Windows Store project, you have an option to add Share Target Contract to your app (see Figure 2-23). This step adds the appropriate declaration to the package manifest and adds a new page, which is used by other apps to share content with your app.

Two screenshots showing a Visual Studio dialog box and window. The Share Target Contract option is highlighted in the Add New Item dialog box. The Search and Share Target declarations appear in the package manifest window.

Figure 2-23. Adding the Share Target contract in a Windows Store app

Visual Studio adds the following code when your app is activated for sharing by another Windows Store app when content is ready to be shared:

// Invoked when the application is activated as the target of a sharing operation. protected override void OnShareTargetActivated(ShareTargetActivatedEventArgs args)

{

var shareTargetPage = new ShareTargetSample.ShareTargetPage();

shareTargetPage.Activate(args);

}

If your app includes the Share Target contract, the app will appear in the list of available apps for sharing user content. If you select your app, a basic UI for the Share Target page appears, as shown in Figure 2-24.

Two screenshots. The screenshot on the left is the Share pane in a Windows Store app listing applications available for sharing content: Mail, 70-484-ShareTargetApp, and People. The screenshot on the right is the default Share Target page hosted in the Share pane of the app chosen by the user to share content. It is named Microsoft Store Locations, displays a URL, and displays a text box with a Share button.

Figure 2-24. Share pane with your app (left) and the default Share Target page hosted in the Share pane (right)

The data that is shared with your app is contained in the ShareOperation object in the ShareTargetActivatedEventArgs event argument. The OnShareTargetActivated method override added by Visual Studio in the Application class can be used to navigate to the Share Target page in the app. In the OnNavigatedTo method of the Share Target page, you can retrieve the shared data by examining the DataPackageView object, as shown in Navigating to the Share Target page.

NAVIGATING TO THE SHARE TARGET PAGE

// This method defined in the Application class is invoked when the application

// is activated as the target of a sharing operation. It is used to navigate to the

// Share Target page.

protected override void OnShareTargetActivated(ShareTargetActivatedEventArgs args)

{

var rootFrame = new Frame();

rootFrame.Navigate(typeof(ShareTargetPage), args.ShareOperation);

Window.Current.Content = rootFrame;

Window.Current.Activate();

}

// This method defined in the Share Target page is invoked when the page is shown

// to the user.

protected override async void OnNavigatedTo(NavigationEventArgs args)

{

ShareOperation shareOperation = (ShareOperation)args.Parameter;

this._shareOperation = ShareOperation; // Save a copy for use in other events

this.sharedDataTitle = shareOperation.Data.Properties.Title;

this.sharedDataDescription = shareOperation.Data.Properties.Description;

// Check the DataPackageView for the data formats and use them accordingly

if (shareOperation.Data.Contains(StandardDataFormats.Uri))

{

try

{

this.sharedUri = await ShareOperation.Data.GetUriAsync();

}

catch (Exception)

{

// Notify user of the exception.

}

}

if (shareOperation.Data.Contains(StandardDataFormats.Text))

{

try

{

this.sharedText = await ShareOperation.Text.GetUriAsync();

}

catch (Exception)

{

// Notify user of the exception.

}

}

}

Visual Studio adds the Text and URI data formats in the package manifest when the Share Target template is used. You can add more data formats in the package manifest of your app; these formats are mapped to the members of the StandardDataFormat enumeration. The system extracts information about your app’s supported data formats and file types from the package manifest. It is therefore important to update the manifest with the data formats and file types your app supports, as shown in Figure 2-25.

A partial screenshot of the package manifest in Visual Studio showing the data formats and file types in a Windows Store app. Data format options that are displayed include Text, URI, HTML, and StorageItems. The bottom part of the screenshot shows supported file types, with JPG selected.

Figure 2-25. Data formats and file types supported in a Windows Store app specified in the package manifest

When a user has selected your app to share content, you should not force the user to remain with the share UI if your app takes time to parse the data to be shared. You should instead use the ReportStarted method of the ShareOperation object to inform the system that your app is processing the request to share content. This ensures the share operation continues to run in your app even after the user dismisses the share UI and returns to the source app.

The user can dismiss the source app before your app has finished acquiring data from the DataPackage object. Therefore, you should notify the system with the ReportDataRetrieved method of the ShareOperation object when your app has all the data it expects from the source app. The system can then suspend or terminate the source app.

In some apps, the share operation can include instructions to retrieve the content to be shared from a remote location. For example, the URI of a resource is shared instead of the resource itself. The target application downloads the resource from the URI as part of the share operation. The target application typically uses background transfer to download the resource and notify the system that a background transfer is under way with the ReportSubmittedBackgroundTask method of the ShareOperation object.

If there is an error during the share operation, your app can report it with the ReportError method of the ShareOperation object. At such a point, the target app shuts down and the share operation ends. The user will have to start the share operation again.

When your app successfully processes the shared content, you should call the ReportCompleted method of the ShareOperation object to notify the system that the share operation has completed. The Share charm that displays the Share Target page from your app is dismissed after the share operation is complete.

Methods provided by the ShareOperation class are invoked only once in the order described previously when the user chooses your app to share content. However, a target app can call ReportDataRetrieved before calling the ReportStarted method. An example is when the app retrieves the data as part of a task in the activation handler but doesn’t call the ReportStarted method until the user clicks the Share button. Unhandled exceptions in a target app terminate it immediately. Therefore, a Windows Store app should handle exceptions arising from invalid data and report them to the user. Perform long-running operations in the background; otherwise, the system assumes your app is not responding and displays an error. You should store the ShareOperation object and process data asynchronously in your app.

Implementing the Share Target contract is a great way to make your app stand out among other Windows Store apps. Windows 8 lists apps used previously for sharing content in a list when the user opens the Share charm. This is supported via QuickLinks, which are shortcuts preconfigured with information required for sharing content. For example, you frequently share content with a friend using email. Your app can create a QuickLink that creates a new email message preconfigured with your friend’s email address.

A QuickLink created by your app is returned to the system by calling the ReportCompleted method of the ShareOperation object. A QuickLink consists of a title, an icon, and an ID. The title and icon appear when the user opens the Share charm. Creating a QuickLink for a share operation and reporting it shows how to create a QuickLink for a share operation and report it using the ReportCompleted method of the ShareOperation class.

CREATING A QUICKLINK FOR A SHARE OPERATION AND REPORTING IT

QuickLink quickLinkInfo = new QuickLink

{

Id = QuickLinkId.Text,

Title = QuickLinkTitle.Text,

// For QuickLinks, the supported FileTypes and DataFormats

// are set independently from the manifest.

SupportedFileTypes = { "*" },

SupportedDataFormats =

{

StandardDataFormats.Text,

StandardDataFormats.Uri,

StandardDataFormats.Bitmap,

StandardDataFormats.StorageItems,

StandardDataFormats.Html

}

};

try

{

StorageFile iconFile = await

Package.Current.InstalledLocation.CreateFileAsync("assets\\user.png",

CreationCollisionOption.OpenIfExists);

quickLinkInfo.Thumbnail = RandomAccessStreamReference.CreateFromFile(iconFile);

this._shareOperation.ReportCompleted(quickLinkInfo);

}

catch (Exception ex)

{

// Even if the QuickLink cannot be created it is important

// to call ReportCompleted. Otherwise, if this is a long-running share,

// the app will stick around in the long-running share progress list.

this._shareOperation.ReportError("Error during share operation (" + ex.ToString()

+ ")");

this._shareOperation.ReportCompleted();

throw;

}

Limiting the scope of sharing using the DataPackage object

Whether your Windows Store app acts as a share source or share target, you should consider the data formats and file types your app will support. If your app acts as a share source, it cannot obtain the data formats supported by the target app chosen by the user for sharing the content from your app. If your app is sharing formatted text from a web page, it is a good practice to include plain text versions of the content and perhaps the URL from where the content originated.

Windows provides a number of built-in data formats that can be used with the DataPackage class. These formats are represented as static properties of the StandardDataFormats class that return the string values used to declare the data formats supported by an app in its package manifest. The formats are as follows:

§ Bitmap. Bitmap format, used for sharing images

§ Html. HTML format, used for sharing HTML content

§ Rtf. Rich Text Format, used for sharing RTF content

§ StorageItems. StorageItem format, used for sharing files

§ Text. Text format, used for sharing plain text

§ Uri. Uniform resource identifier (URI) format, used for sharing URIs

The DataPackage class provides methods to share data in the formats represented by the StandardDataFormats class. These methods are the following:

§ SetBitmap. Sets the bitmap image present in the DataPackage object (as a RandomAccessStreamReference).

§ SetHtmlFormat. Sets the HTML content.

§ SetRtf. Sets the RTF content contained in a document.

§ SetStorageItems. Sets the files and folders contained in a DataPackage object. You can specify if the files are read-only by using a Boolean flag.

§ SetText. Sets the text.

§ SetUri. Sets the URI.

You have the option to support all the formats represented by the StandardDataFormats class in your app that is a share target. If all the formats are present in the content being shared, it is recommended you process the format most relevant for the sharing operation. For example, if your app shares images and it receives content that contains the image and URI of the location of the images, your app should process the image.

In some cases, you can choose to define a custom format and use it to share content from your app. For example, if your app is a movie titles browser, users can choose to share the title, rating, director, and cast of a movie. Because the data to be shared is more specific than the standard formats supported, you should consider supporting one of the many schemas at http://www.schema.org and prepare the data package accordingly. If you cannot find a schema at Schema.org, consider using a format ID such as Windows8-Preview-<schema>. In your app, you can collect information about the content to be shared, package the content in the JavaScript Object Notation (JSON) format, and use SetData to add the content to the DataPackage. In the SetData method, the schema name is used as the key for the JSON data being shared. The share target application uses the schema name to extract the JSON data.

If your app is a share target and supports one or more custom formats, you should add a data format that identifies the schema supported by your app in your app’s manifest. In the package manifest, use Windows-8-Preview-<schema> as the data format, where <schema> is the name of the schema your app supports. If you cannot find a schema at Schema.org that fulfills the requirements of your app, you can create your own custom format. In this case, you should choose a name and use it in both the source and target app as well as considering publishing the format so that other developers can benefit from it.

In some Windows Store apps, preparing data when sharing content with other apps can take significant time. For example, if your app resizes images before sharing them with the target app, the resizing operation can take a significant amount of time before the data is ready for sharing. You should use the SetDataProvider method of the DataPackage class with a format from the StandardDataFormats class and a DataProviderHandler method that puts data using the SetData method when invoked.

When your app receives data as a share target, a read-only version of the DataPackage class called DataPackageView is used. The DataPackageView object has a property called AvailableFormats that is a read-only list of all the formats that the DataPackageView contains. Alternatively, you can see whether a specific format is present in the DataPackageView object by using the Contains method with the format ID from the StandardDataFormats class. The Contains method returns True if the format is present in the shared content; otherwise, it returns False.

Implementing in-app share outside the Share charm

Windows Store apps that act as a share source integrate the sharing experience through the Share charm. These apps use the DataRequested event handler with the DataPackage class to share content with other apps. In some apps, sharing content through the Share charm can result in a poor user experience, for example, when a game is active, and the user wants to share their score with other players. You should not expect the user to open the Share charm by swiping the right edge of the screen or through the Windows+C keyboard shortcut. In such cases, you should use theShowShareUI method of the DataTransferManager class to launch the Share charm, as shown in the following code:

// Namespace usings removed for brevity

protected void ShowUIButton_Click(object sender, RoutedEventArgs args)

{

DataTransferManager.ShowShareUI();

}

THOUGHT EXPERIMENT

Adding share support in your Windows Store app

In this thought experiment, apply what you’ve learned about this objective. You can find answers to these questions in the “Answers” section at the end of this chapter.

One of the updates you planned after releasing your Windows Store app was to incorporate sharing of content via the Share Target contract. You have implemented the Share Target contract and are ready to submit the update to the Windows Store.

While reading reviews of other Windows Store apps, you realize your app connects to popular social networking sites and your app should be a share target.

Answer the following questions to help determine the feasibility of supporting the Share Target contract:

1. Can a Windows Store app act as a share source and share target at the same time? If yes, are there any limitations on these features if both are included in the same app?

2. What should you consider so that most Windows Store apps can use the data you have shared with your app as a share source?

3. You want most Windows Store apps to be able to use your app to share data. What should you do to ensure your app can act as a share target with most Windows Store apps?

Objective summary

§ Windows Store apps should share data with other apps through the Share charm to provide a simple, in-context and rich user experience.

§ You should use the DataTransferManager class along with the DataPackage class to implement sharing from your app as a source. The data formats and file types supported by your app should be declared in the package manifest.

§ If processing data shared from an app takes a fair amount of time to complete, consider using background tasks to avoid your app from being unresponsive.

§ Your app should implement the Share Target contract to promote itself among other apps. Users might find your app convenient to use for sharing content and use it regularly, which in turn will make it appear in the list of apps available for sharing content if it implements the Share Target contract.

§ Windows provides standard formats to share data. You can use a custom data format, such as those defined at Schema.org, or create your own. You can publish your custom format, if you create one, for other apps to use.

Objective review

Answer the following questions to test your knowledge of the information in this objective. You can find the answers to these questions and explanations of why each answer choice is correct or incorrect in the “Answers” section at the end of this chapter.

1. You are about to implement shared content via your app. Which event should you handle to provide the data you plan to share from an app page?

a. OnNavigatedTo

b. OnNavigatedFrom

c. DataRequested

d. Loaded

2. After you finish processing the data shared by another app, which method should you invoke to inform the system of completion?

a. ReportCompleted

b. ReportDataRetrieved

c. ReportStarted

d. ReportError

3. You are developing a game from which you will allow users to share their achievements with other users. You cannot exit the UI nor can you use the charms bar to open the Share charm. What is the best solution for such a requirement?

a. Save the data in local storage and share it later when the app resumes.

b. Save the data in local storage and upload it to a server using background tasks.

c. Use DataTransferManager.ShowShareUI() to programmatically open the Share charm.

d. Use DataTransferManager.GetForCurrentView() to programmatically open the Share charm.

Objective 2.5: Manage app settings and preferences

Windows Store apps can integrate with the Settings charm and provide their own links that invoke commands, open their settings page, and so on. The Settings pane is populated with commands from your app and displays various system functions at the bottom. Windows adds a Rate & Review command if the app was downloaded and installed from the Windows Store and a Permissions command if the app has capabilities declared in the manifest.

The Settings charm is available from within any page in a Windows Store app and provides a simple way to update its global settings. You can construct a Settings pane using the Popup control, and provide standard Windows 8 controls such as toggle buttons to configure app settings. The application settings can be saved in the roaming data store so users can access them after closing and restarting the app.

NOTE

This objective covers how to:

§ Choose which app features are accessed in AppSettings.

§ Add entry points for AppSettings in the Settings window.

§ Create settings flyouts using the Popup control.

§ Add settings to Popup.

§ Store and retrieve settings from the roaming app data store.

Choosing which app features are accessed in AppSettings

Windows Store apps can provide users with a consistent way to access app settings. You should use the Settings charm as the primary entry point of your app’s settings and put all your settings in the Settings pane. If your app has more than one category of settings, consider using settings flyouts for each category. Use as few settings as possible in your app and provide defaults for all of them. Your app should immediately implement a settings change, such as changing the default font size, because a settings flyout can close immediately if the user touches or clicks anywhere outside the flyout.

It is important to carefully consider the settings you want to make available through the Settings charm. Here are some guidelines for adding settings to your app:

§ Add settings that are occasionally changed by the user, for example, the font size of text in an RSS reader app or the temperature units in a weather app.

§ If your app logs in to a remote service, provide a command to the user to log out and an option to remember your credentials in the PC.

§ Add user preference options, such as color themes or data refresh intervals.

§ Add information about your app that is occasionally used, such as the privacy policy, help, copyright, and app version.

It is recommended that you use up to four entry points (from a maximum of eight) for grouping similar or related options together. These entry points should be visible wherever the user is in your app. You can disable some settings in a certain context. Each entry point in the Settings pane should use a single word as a label. If a command opens a web page instead of a flyout, you should inform your users with a visual clue.

Adding entry points for AppSettings in the Settings window

Unlike the Search Target contract or the Share Target contract, a Windows Store app that provides access to its settings through the Settings charm does not require a capability or a declaration in the package manifest. Entry points for AppSettings are added in the CommandsRequested event of the SettingsPane object, as shown in Adding entry points for AppSettings in the CommandsRequested event.

ADDING ENTRY POINTS FOR APPSETTINGS IN THE COMMANDSREQUESTED EVENT

using Windows.UI.ApplicationSettings;

// Other namespace usings removed for brevity

public sealed partial class App : Application

{

public OnWindowCreated()

{

SettingsPane.GetForCurrentView().CommandsRequested += OnCommandsRequested;

}

void OnCommandsRequested(SettingsPane sender,

SettingsPaneCommandsRequestedEventArgs e)

{

e.Request.ApplicationCommands.Add(

new SettingsCommand(1, "Account", OnAccountCommand));

e.Request.ApplicationCommands.Add(

new SettingsCommand(2, "General", OnGeneralCommand));

e.Request.ApplicationCommands.Add(

new SettingsCommand(3, "Theme", OnThemeCommand));

e.Request.ApplicationCommands.Add(

new SettingsCommand(4, "Credits", OnCreditsCommand));

e.Request.ApplicationCommands.Add(

new SettingsCommand(4, "Feedback", OnFeedbackCommand));

}

void OnAccountCommand(IUICommand command)

{

// Show the account settings pane

}

void OnGeneralCommand(IUICommand command)

{

// Show the general settings pane

}

void OnThemeCommand(IUICommand command)

{

// Show the theme settings pane

}

void OnCreditsCommand(IUICommand command)

{

// Show the credits pane

}

void OnFeedbackCommand(IUICommand command)

{

// Show the feedback pane

}

}

The commands are integrated and shown in the Settings pane when the application is run, as shown in Figure 2-26.

A screenshot of the Settings charm showing the entry points for settings in a Windows Store app. The options include Account, General, Theme, Credits, Feedback, and Permissions.

Figure 2-26. Entry points for the Windows Store app available in the Settings charm

The content of the settings flyout for the Permissions command is prepared from the capabilities declared in the package manifest, as shown in Figure 2-27.

Two screenshots. The screenshot on the left shows the Internet (Client), Music Library, and Pictures Library capabilities selected in the package manifest of a Windows Store app. The same capabilities appear in the screenshot on the right, which shows the Permissions screen for the app.

Figure 2-27. Capabilities declared in the package manifest and listed in the app’s permissions, available as a command in the Settings charm

Creating settings flyouts using the Popup control

When a command is clicked in the Settings charm, your app should display a UI similar to the Settings pane. You are not allowed to add controls into the Settings pane itself; instead, you should provide your own control that is loaded into the UI provided by the Settings pane.

One way to implement your own Settings pane is to create a XAML user control that can be reused across your app. A simple way to display content inside the SettingsPane class is to use the Popup control, as shown in the XAML in Using the Popup control to display content in the SettingsPane class.

USING THE POPUP CONTROL TO DISPLAY CONTENT IN THE SETTINGSPANE CLASS

<UserControl x:Class="70-484SettingsApp.ThemeSettingsPane"

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

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

<Popup x:Name="settingsPopup" IsLightDismissEnabled="True"

Closed="SettingsPopup_Closed"

HorizontalAlignment="Right" Width="345">

<Popup.Transitions>

<TransitionCollection>

<PaneThemeTransition/>

</TransitionCollection>

</Popup.Transitions>

<Grid x:Name="popupGrid" Width="345">

<StackPanel VerticalAlignment="Top" Margin="21,30,0,0">

<!-- The header, with a back button and title -->

<StackPanel Orientation="Horizontal">

<Button Style="{StaticResource SnappedBackButtonStyle}"

Click="BackButton_Click"/>

<TextBlock Text="Application Settings" FontWeight="Normal"

Style="{StaticResource SubheaderTextStyle}"

Margin="-2,-2,0,0"/>

</StackPanel>

<!-- Controls for specific flyout go here -->

</StackPanel>

</Grid>

</Popup>

</UserControl>

The user control created for the settings flyout uses the same transitions as the Settings pane, ensuring the user experience is maintained. The PaneThemeTransition is invoked when an element initially enters the view. Therefore, the Popup must be detached from the layout and reattached every time it is displayed. In addition, the height of the Popup is set to the screen’s height.

The Back button of the user control shows the Settings pane programmatically. The code-behind of the control is shown in Creating a user control for the Settings pane.

CREATING A USER CONTROL FOR THE SETTINGS PANE

using Windows.UI.ApplicationSettings;

// Other namespace usings removed for brevity

public sealed partial class ThemeSettingsPane: UserControl

{

public ThemeSettingsPane()

{

this.InitializeComponent();

// This will invoke the PaneThemeTransition when the control is

// displayed again.

this.Content = null;

// Set the pane's height to the height of the screen

this.LayoutUpdated += (sender, e) =>

{

this.popupGrid.Height = this.ActualHeight;

};

}

// Display the popup

public void Show(IUICommand command)

{

this.Content = this.settingsPopup;

this.settingsPopup.IsOpen = true;

}

// Detach the popup from the content, this will invoke the PaneThemeTransition

private void SettingsPopup_Closed(object sender, object e)

{

this.Content = null;

}

private void BackButton_Click(object sender, RoutedEventArgs args)

{

SettingsPane.Show();

}

}

Adding settings to Popup

With the settings flyout created using the Popup control, you can add settings for a Windows Store app in the XAML. Use data binding to read and set values for these settings added as controls in the XAML. Using a ToggleSwitch control to switch between a dark theme and a light themeshows how a ToggleSwitch control can be used to toggle between a dark theme and a light theme of an app.

USING A TOGGLESWITCH CONTROL TO SWITCH BETWEEN A DARK THEME AND A LIGHT THEME

<UserControl x:Class="70-484SettingsApp.ThemeSettingsPane"

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

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

<Popup x:Name="settingsPopup" IsLightDismissEnabled="True"

Closed="SettingsPopup_Closed"

HorizontalAlignment="Right" Width="345">

<Popup.Transitions>

<TransitionCollection>

<PaneThemeTransition/>

</TransitionCollection>

</Popup.Transitions>

<Grid x:Name="popupGrid" Width="345">

<StackPanel VerticalAlignment="Top" Margin="21,30,0,0">

<!-- The header, with a back button and title -->

<StackPanel Orientation="Horizontal">

<Button Style="{StaticResource SnappedBackButtonStyle}"

Click="BackButton_Click"/>

<TextBlock Text="{Binding PaneTitle}" FontWeight="Normal"

Style="{StaticResource SubheaderTextStyle}"

Margin="-2,-2,0,0"/>

</StackPanel>

<!-- Controls for specific flyout go here -->

<StackPanel Margin="13,0,0,0">

<!-- The LightThemeOn variable is data-bound to a property

that is used to set the theme of the application. In the

simplest form, it is used to change the background color -->

<ToggleSwitch Header="Use Light Theme"

IsOn="{Binding LightThemeOn}" />

</StackPanel>

</StackPanel>

</Grid>

</Popup>

</UserControl>

The flyout with the Settings pane for a Windows Store app is shown in Figure 2-28.

A screenshot of the settings flyout implemented using a Popup control for a Windows Store app. The screenshot shows the Use Light Theme option with an On/Off toggle switch.

Figure 2-28. Settings flyout implemented using a Popup control for a Windows Store app

Storing and retrieving settings from the roaming app data store

Windows 8 provides three application data stores: local, roaming, and temporary. When designing your app’s data layer, you should consider one of these stores for a particular kind of application data.

You can save an application’s settings and user preferences to a roaming app data store, which retains the information and makes it available across multiple devices. If a user has your app installed on one device and then downloads and installs it on another device, the data saved in the roaming data store in the first device will be available on the second device, and vice versa. Therefore, using the roaming app data store to save app settings will provide a uniform experience to the user across multiple devices.

You should consider application data such as view preferences, background color or theme customization, and similar settings in your app to be saved in the roaming app data store. In addition, you can also save the last position in the app’s context, such as a news item being read, game level and score data, and navigation history.

IMPORTANT USAGE OF THE ROAMING DATA STORE

You should not use the roaming app data store to save data relevant to a device, such as the path to a local file resource on a PC. Note that roaming data is not synchronized instantaneously and therefore should not be used to store frequently changing information such as up to the second position in a movie or a song.

In a Windows Store app, you must use the roaming app data store via the RoamingSettings property of the ApplicationData object. A new ApplicationDataContainer is created to store your application’s settings. You must subscribe to the DataChanged event to receive changes in the data stored in the roaming data store and raise a data changed event by calling SignalDataChanged to notify a change in the data stored in the roaming data store. This process is shown in the C# code in Subscribing to the DataChanged event to receive changes in the data stored.

SUBSCRIBING TO THE DATACHANGED EVENT TO RECEIVE CHANGES IN THE DATA STORED

using Windows.UI.Storage;

// Other namespace usings removed for brevity

public sealed partial class MainPage : Page

{

ApplicationData applicationData = null;

ApplicationDataContainer roamingSettings = null;

public MainPage()

{

this.InitializeComponent();

applicationData = ApplicationData.Current;

roamingSettings = applicationData.RoamingSettings;

applicationData.DataChanged += DataChangedHandler;

}

// Update the theme and store the modified settings

public void UpdateSettings(bool useLightTheme)

{

roamingSettings.Values["Theme"] = useLightTheme;

// Update the theme based on the user's choice

// Signal a change in settings

applicationData.SignalDataChanged();

}

// Event handler that is invoked whenever the data in the roaming store changes

private async void DataChangedHandler(ApplicationData appData, object e)

{

// Data has changed, update settings

if (roamingSettings.Values.ContainsKey("Theme"))

{

bool theme = (bool) roamingSettings.Values["Theme"];

// Update the theme if it is has changed

}

}

}

Composite values can be used to store a number of settings as key/value pairs in the roaming data store. If you are required to store and retrieve composite values, you can do so using the following C# code:

using Windows.Storage;

//

//

ApplicationDataCompositeValue compositeVal = new ApplicationDataCompositeValue();

compositeVal["Theme"] = false;

compositeVal["FontSize"] = 18;

roamingSettings.Values["themeSettings"] = compositeVal;

Each app has a quota for roaming application data. You should check the ApplicationData.RoamingStorageQuota property to obtain the total size of roaming data allowed.

THOUGHT EXPERIMENT

Using the Settings charm and application settings

In this thought experiment, apply what you’ve learned about this objective. You can find answers to these questions in the “Answers” section at the end of this chapter.

You have been engaged as a consultant to review the current set of features of a Windows Store app, interview existing customers, and suggest recommendations. The Windows Store app is used by a number of fleet sales agents who are on the road most of the day as well as employees in the headquarters.

During the interview process, you have discovered a number of shortcomings in the app, particularly around application settings and how the Settings charm is used in the app.

You have found that the primary form of communication is by email created through a page in the app itself. There is a page specifically for application settings, and most of the configuration is static. You have also found that data for the app is tied to the user and the device.

What are the top three recommendations you incorporate in a report to the managing director of the company?

Objective summary

§ A Windows Store app should integrate with the Settings charm and provide one or more Settings panes with commands to invoke the panes. The panes can contain a group of application settings, grouped by their type.

§ You should include properties, such as background color and font size used in an app in the Settings, to allow the user to configure their preferences.

§ You should create and use settings flyouts using the Popup control, providing a flyout for each Settings command.

§ You should use as few controls as possible in the settings flyouts, providing default values for the controls wherever possible.

§ You should use the roaming app data store to save user settings. This will ensure that the settings are persisted across multiple devices, providing a great user experience.

Objective review

Answer the following questions to test your knowledge of the information in this objective. You can find the answers to these questions and explanations of why each answer choice is correct or incorrect in the “Answers” section at the end of this chapter.

1. You are developing a Windows Store game and want to save user settings when the app is suspended. Which data storage strategy should you use?

a. Save the settings in local storage and retrieve when needed.

b. Save in the local registry and read from it when needed.

c. Save in the roaming app data store and read from it when needed.

d. Save in the local directory and read from the file when needed.

2. You are required to provide a list of permissions used in your app. This list is displayed via the Settings charm. How should you implement this requirement?

a. Create a command in the Settings charm. When it is fired, a pop-up dialog box opens with a list of all the permissions used by the app.

b. The package manifest is used to declare all the capabilities used by the app. The Permissions command automatically populates the Settings pane with this list.

c. Create a command in the Settings charm. When it is fired, a settings flyout opens with a list of all the permissions used by the app.

d. Create a command in the Settings charm. When it is fired, navigate the user to a new page that displays a list of all the permissions used by the app.

3. You are using roaming app data storage to store the settings of your app. Your app should update the stored settings whenever the user changes them. What should you do to implement this requirement?

a. Nothing; data is automatically updated in the data store by the Settings contract.

b. Call the SignalDataChanged method after saving the data in the ApplicationDataContainer.

c. Subscribe to the DataChanged event; when this event is raised, save the updated data in the roaming store.

d. When the app is being suspended, save a copy of the data in the roaming app data store.

Chapter summary

§ Windows Store apps can use the ContactPicker and ContactPickerUI classes to provide contacts to other apps. The ContactPicker class supports the selection of a single contact or multiple contacts at a time.

§ Contacts can be filtered and selected by specifying the fields used in the selection using the KnownContactField class. Selected fields of a contact can be displayed using the ContactFieldCategory and ContactFieldType classes.

§ Whenever possible, you should integrate your app with the charms bar and the Search, Share Target, Settings, and Devices contracts. This helps your app to be popular among your users as they find it easier to use your app for searching and sharing content.

§ You should configure your app’s manifest with the right permissions. This is important when you support various contracts in your app.

§ You should provide search result previews in your app. This helps users to easily select an item from the search result.

§ Query suggestions and result recommendations enrich the search experience for the user; you should consider implementing them in your app whenever possible.

§ Your app is discovered and used more often if you support activation by search. Users can pick your app to carry out their search even if your app is not running.

§ If your application has content to share, consider implementing the code to set up your app as a share source. You should consider supporting as many formats as possible so that the user has multiple choices of apps to use for sharing content from your app.

§ While accepting share requests from other apps, you should support as many formats as possible. This enables your app to be used in most scenarios. Add a QuickLink for a sharing action; this helps your app to be found in the list of suggested apps available for sharing content.

§ Use the DataPackage and DataPackageView objects to share data and view shared data, respectively. If you require a custom format to share data, check the custom formats already available.

§ Your app should provide the user to customize settings per their preference. You should have about four commands that open the settings flyout with a set of controls.

§ You should use a roaming app data store to save the applicable settings of your app. This helps with having the user’s settings available across multiple devices.

Answers

This section contains the solutions to the thought experiments and answers to the lesson review questions in this chapter.

Objective 2.1: Thought experiment

1. Yes. A Windows Store app can act as a contact provider while including other features such as importing data from local and remote sources.

2. One of the requirements of the ContactPickerUI class is that the application should not be in the snapped state. You should check the app’s view state and try to unsnap it if it is in the snapped state.

3. Yes. If the calling application uses PickMultipleContactsAsync, users will be able to select more than one contact at any time. Users will be able to select one contact at a time if PickSingleContactAsync is used.

Objective 2.1: Review

1. Correct answers: A, D, E

a. Correct: Name is a property of the ContactInformation class.

b. Incorrect: Designation is not a property of the ContactInformation class.

c. Incorrect: Organization Name is not a property of the ContactInformation class.

d. Correct: The Locations property of the ContactInformation class contains the work address.

e. Correct: The PhoneNumbers property of the ContactInformation class contains the work phone number.

2. Correct answer: C

a. Incorrect: Because PickSingleContactAsync is called within a while loop that never exits; therefore, the user will not be able to select a contact.

b. Incorrect: The PickMultipleContactsAsync method does not return a list of Contact objects.

c. Correct: The PickMultipleContactsAsync method returns a read-only list of ContactInformation objects.

d. Incorrect: The PickMultipleContactsAsync method must be invoked asynchronously.

3. Correct answer: B

a. Incorrect: The app should always check for the application’s view state.

b. Correct: The ContactPickerUI can be used when the app is in the filled state.

c. Incorrect: The ContactPickerUI does not function in the snapped state of an app.

d. Incorrect: The view state of the application should be checked by the app itself.

Objective 2.2: Thought experiment

1. You should implement the Search contract in your app with the OnSearchActivated event implemented to make sure your app is activated if it is selected during the search. You should consider including search suggestions and recommendations.

2. You should implement content sharing in the pages of your app. Doing so ensures that third-party apps such as the Mail application can be used to share content from within your app.

3. You should use the Devices charm to discover printers in the network and allow the app to select a printer and print content.

Objective 2.2: Review

1. Correct answers: C, D, E

a. Incorrect: The charms bar is available on all Windows 8 and WinRT devices.

b. Incorrect: An app should use find-in-page to search within a page; the search contract is used to search within the whole app.

c. Correct: A Windows Store app that implements a mechanism to share content from other apps must implement the Share Target contract.

d. Correct: The Settings charm is available to all Windows Store apps. The Settings charm can be used to provide users with a way to customize the application’s settings.

e. Correct: Query suggestions and result recommendations enable users to quickly search for content and access content that they frequently view with the app.

2. Correct answers: A, B, D

a. Correct: Account/session management is a user-specific requirement and hence should be included in the Settings charm.

b. Correct: Theme preferences are specific to the user and should be included in the Settings charm.

c. Incorrect: Windows Store apps are closed with a gesture (pressing down on the app at the top and dragging it down), and applications are not allowed to provide a way to close them.

d. Correct: The Settings charm is the right location for a feedback form.

e. Incorrect: An app should use find-in-page to search within an app.

3. Correct answer: C

a. Incorrect: The OnWindowCreated method is invoked by the system when the application creates a window.

b. Incorrect: The OnLaunched method is invoked by the system when the application is launched.

c. Correct: The OnSearchActivated method is invoked when the application is opened through a search query.

d. Incorrect: The OnActivated method is invoked when the application is opened by any means other than the user launching the app. Because the activation kind needs to be checked to determine the source that activated the app, it is better to use OnSearchActivated method to support app activation via search.

Objective 2.3: Thought experiment

1. Update the package manifest to declare your app implements the Search contract. Implement code to handle the QuerySubmitted and QueryChanged event. Check to see whether the query string is empty and show the default page to the user if it is empty.

2. Provide the user with query suggestions and result recommendations. If the user clicks a result recommendation and views the result in the app, prepare a QuickLink for the result recommendation so that your app appears in the list of apps available for search.

3. If a user is in your app and begins typing, open the Search charm and allow the user to carry out search.

4. Implement the OnSearchActivated event so that your app is activated whenever it is selected to carry out the search.

Objective 2.3: Review

1. Correct answers: A, B, D

a. Correct: Use the QuerySubmitted event to carry out the search using the query text entered by the user.

b. Correct: Use the QueryChanged event to obtain the text entered by the user in the Search charm and carry out the search.

c. Incorrect: The Loaded event is fired when the page is loaded. It is likely that the search operation is underway while the page finishes loading; therefore, the Loaded event is not required to implement search.

d. Correct: The OnSearchActivated method is invoked when the app is opened by the user carrying out a search with the app when it is not running and visible.

e. Incorrect: The Unloaded event is fired after the page is unloaded; therefore, it is not useful for implementing search.

2. Correct answer: B

a. Incorrect: The QueryChanged event is raised when the search query text entered by the user changes.

b. Correct: The SuggestionsRequested event fires when the user’s query text changes, and the app needs to provide suggestions.

c. Incorrect: The ResultSuggestionChosen event fires when the user selects a result recommendation from the list provided in the Search charm.

d. Incorrect: The QuerySubmitted event is raised when the user submits a query to commence search.

3. Correct answer: A

a. Correct: The ResultSuggestionChosen event fires when the user selects one of the suggested results provided by the app and displayed in the Search charm.

b. Incorrect: The QuerySubmitted event fires when the user submits text in the search box, and the app is expected to carry out the search.

c. Incorrect: The QueryChanged event fires when the user changes the query text in the search box.

d. Incorrect: The SuggestionsRequested event fires when the query text in the search box is changed by the user, and the app needs to provide new suggestions.

Objective 2.4: Thought experiment

1. Yes, a Windows Store app can act as both share source and target. There are no limitations on the features of share source and target if both are present in the same app.

2. Data should be packaged so that published formats are used in the data package. This ensures that a maximum numbers of Windows Store apps can read the data.

3. Your app should support data to be provided in a data package, and it should be able to parse the DataPackage for common formats.

Objective 2.4: Review

1. Correct answer: C

a. Incorrect: The OnNavigatedTo method is invoked only once when the page is about to be navigated to. This method can be used to subscribe to the DataRequested event.

b. Incorrect: The OnNavigatedFrom method is invoked when the page is navigated away from. This method can be used to unsubscribe from the DataRequested event.

c. Correct: The DataRequested event is used to provide the data to be shared by an app.

d. Incorrect: The Loaded event fires when the page is first loaded.

2. Correct answer: B

a. Incorrect: The ReportCompleted method should be used to inform the system that the share operation has completed.

b. Correct: The ReportDataRetrieved method should be used to report completion of processing of data shared by the source app.

c. Incorrect: The ReportStarted method is used to inform the system that the app has started to retrieve the data shared by another app.

d. Incorrect: The ReportError method is used to inform the system the sharing process encountered an error.

3. Correct answer: C

a. Incorrect: The Share Target contract is used with data that is currently available within the app.

b. Incorrect: Although you can use background tasks to synchronize data with remote servers, sharing a result should be done without any delays.

c. Correct: The ShowShareUI method of the DataTransferManager class can be used to programmatically open the Share charm.

d. Incorrect: The GetForCurrentView method of the DataTransferManager class is used to retrieve an instance of the search pane from which users can search within the app.

Objective 2.5: Thought experiment

1. Application settings that do not store values specific to a PC or a device, such as the path to a file, should be stored in the roaming app data store. This will ensure data is available on all the devices and PCs accessed by the user.

2. The settings flyout should be used to send custom data to other users. If required, the app should programmatically open the Share charm and provide the user the choice of selecting a Windows Store app to share their data.

3. The app should employ the Settings charm to incorporate the settings required for the app. The app should provide default values for the settings and it should minimize the amount of configurable parameters as much as possible.

Objective 2.5: Review

1. Correct answer: C

a. Incorrect: Settings and preferences stored in local storage are not available on other devices.

b. Incorrect: Settings and preferences stored in the registry of the device are not available on other devices.

c. Correct: Settings and preferences stored in roaming storage are available on other devices.

d. Incorrect: A file can be used to store and retrieve data, but it is not available on other devices.

2. Correct answer: B

a. Incorrect: The app manifest contains a list of all the capabilities declared by the app. This list is displayed in the Permissions command in the Settings pane; there is no need to display the list in a pop-up window.

b. Correct: The app manifest has a list of all the capabilities declared by the app. This list is displayed in the Permissions command in the Settings pane.

c. Incorrect: The app manifest has a list of all the capabilities declared by the app. This list is displayed in the Permissions command in the Settings pane; there is no need to display the list in a settings flyout.

d. Incorrect: The app manifest has a list of all the capabilities declared by the app. This list is displayed in the Permissions command in the Settings pane; there is no need for the user to navigate to a different page.

3. Correct answer: B

a. Incorrect: Application data is not updated by the Settings contract.

b. Correct: The SignalDataChanged method is provided by the system to notify that the data stored in the roaming store has changed.

c. Incorrect: The DataChanged event informs Windows Store apps that data stored in the roaming store has changed.

d. Incorrect: Although you can save a copy of the data in the roaming app data store when the app is being suspended, to propagate any changes in the data, you should call SignalDataChanged in your app