Synchronization for Windows Azure and Windows Phone 7

Version 3.0 of the Sync Framework includes providers for Windows Azure and Windows Phone 7 that can exchange synchronization messages using the OData Sync protocol. The samples available for the Sync Framework include examples that use these providers. The Windows Phone 7 provider uses isolated storage on the device to hold the local data and the synchronization metadata as a series of collections in the form of a local context.

The Sync Framework includes a utility named SyncSvcUtil that developers can use to create both a set of entities that extend the IsolatedStorageOfflineEntity base class to define the data types, and a class that extends the IsolatedStorageOfflineContext class to interact
with stored data.

The IsolatedStorageOfflineEntity base class exposes properties used by the Sync Framework provider to define and monitor changes
to the local data. For example, it exposes the entity state (such as Unmodified, Modified, and Saved) if the change encountered a conflict
or error or if the local entity is a tombstone (because it was deleted on the device). The IsolatedStorageOfflineEntity type also exposes events that indicate when the entity value changes and a method to reject the changes and restore the original version.

The concrete type created by the SyncSvcUtil that extends IsolatedStorageOfflineEntity exposes application-specific entity
types based on the schema of the data source with which the device will synchronize. The application on the device uses these entity types
when accessing and interacting with the data that is stored locally.

The IsolatedStorageOfflineContext base class exposes properties, methods, and events that manage the synchronization process and indicate its progress when synchronization is occurring. These include methods to initiate a session, add and remove items, and initiate
synchronization; properties that expose collections of errors and conflicts; and events that indicate the progress and result of the process.

The concrete type created by the SyncSvcUtil utility that extends IsolatedStorageOfflineContext exposes the schema for the stored data, collections of the stored entities, and methods that allow the application to add and delete items in the collections. The application
on the device uses these methods and properties to display and manipulate the data that is stored locally.

To learn more about using the Sync Framework with Windows Azure and Windows Phone 7, see the following resources:

  • “Synchronization” on MSDN: http://msdn.microsoft.com/en-us/library/dd938837(SQL.10).aspx
  • Sync Framework Team Blog: http://blogs.msdn.com/b/sync/

Using the Sync Framework

To perform synchronization, the developer writes code that does the following:

  • Initiates a synchronization session
  • Sets up references to two synchronization providers and configures them appropriately
  • Starts the synchronization process

Each client or server store holds information about the changes occurring in that store. This metadata, stored local to and available to
each provider, contains the knowledge used by the provider to detect changes and conflicts. The Sync Framework includes a small footprint metadata store service that developers can use when implementing custom providers. Alternatively, developers can implement the metadata
functionality as part of the local data store. An example is the offline store provider for Silverlight web applications and Windows phone 7 applications.

Data converters are required if the format of the data is different between the two data stores, and if the existing providers or your custom providers do not expose data in OData Sync format. For example, if one store exposes ADO.NET DataSets and the other exposes data in XML format, the developer can create a pair of data converters and specify these when setting up the synchronization process. If there are many data store formats, it may be easier to create data converters that convert to and
from a common format, and then to use the appropriate pair for each synchronization session.

Events are raised during the synchronization process to indicate the individual changes occurring and any errors that arise (including
conflicts if the data in both locations has changed). The application can handle these events to provide status information to the user,
manage conflicts by applying business rules (such as “latest change wins”), and to display the results.

For a useful introduction to the synchronization process and details of the way that synchronization metadata is used, see “Introduction
to Microsoft Sync Framework” on MSDN (http://msdn.microsoft.com/en-us/sync/bb821992.aspx). This article discusses the metadata used by the framework, the synchronization flow, and includes examples of synchronization with and without update conflicts.

Contents of Prism for Windows Phone 7 Library

Prism Library for Windows Phone 7 contains several namespaces that subdivide the artifacts:

  • Microsoft.Practices.Prism. This namespace contains classes concerned with detecting and reacting to change events for properties and objects.
  • Microsoft.Practices.Prism.Commands. This namespace contains classes concerned with binding commands to user interface (UI) objects without requiring the use of code-behind in the view model, and with composing multiple commands.
  • Microsoft.Practices.Prism.Events. This namespace contains classes concerned with subscribing to events and with publishing events on the publisher thread, UI thread, or a background thread.
  • Microsoft.Practices.Prism.ViewModel. This namespace contains classes that help support implementing the view-model portion of the MVVM pattern, such as displaying a template at run time and simplifying the implementation of property change notification.
  • Microsoft.Practices.Prism.Interactivity. This namespace contains classes and custom behaviors concerned with handling interaction and navigation for application bar buttons and with updating the values of view model properties bound to text and password controls.
  • Microsoft.Practices.Prism.Interactivity.InteractionRequest. This namespace contains classes concerned with displaying notifications to users.

The following tables list the main classes in these namespaces and provide a brief description of their usage. They do not include all the
classes in each namespace; they list only those that implement the primary functions of the library. For a full reference to all the Prism
namespaces, see “Prism (Composite Client Application Guidance)” on MSDN (http://www.microsoft.com/prism).

Microsoft.Practices.Prism Namespace

The following table lists the main components in the Microsoft. Practices.Prism namespace. These classes are not used in the Tailspin application.

Microsoft.Practices.Prism Namespace

Microsoft.Practices.Prism.Commands Namespace

The following table lists the main components in the Microsoft. Practices.Prism.Commands namespace.

Microsoft.Practices.Prism.Commands Namespace

For more information about using the DelegateCommand and CompositeCommand classes, see the section, “MVVM,” in “Prism (Composite Application Guidance)” on MSDN (http://www.microsoft.com/prism).

Microsoft.Practices.Prism.Events Namespace

The following table lists the main components in the Microsoft. Practices.Prism.Events namespace. Classes in this namespace support decoupled communication between pieces of an application, such as between two view models. These classes are not used in the Tailspin application.

Microsoft.Practices.Prism.Events NamespaceMicrosoft.Practices.Prism.Events Namespace

For more information about publishing and subscribing to events, see the section, “Communicating between Loosely Coupled Components,” in “Prism (Composite Application Guidance)” on MSDN (http://www.microsoft.com/prism).

Microsoft.Practices.Prism.ViewModel Namespace

The following table lists the main components in the Microsoft. Practices.Prism.ViewModel namespace.

Microsoft.Practices.Prism.ViewModel Namespace

For more information about using the DataTemplateSelector class, see “MVVM QuickStart” in “Prism (Composite Application Guidance)” on MSDN (http://www.microsoft.com/prism).

Microsoft.Practices.Prism.Interactivity Namespace

The following table lists the main components in the Microsoft. Practices.Prism.Interactivity namespace.

Microsoft.Practices.Prism.Interactivity NamespaceMicrosoft.Practices.Prism.Interactivity Namespace

Microsoft.Practices.Prism.Interactivity. InteractionRequest Namespace

The following table lists the main components in the Microsoft. Practices.Prism.Interactivity.InteractionRequest namespace.

Microsoft.Practices.Prism.Interactivity. InteractionRequest NamespaceMicrosoft.Practices.Prism.Interactivity. InteractionRequest Namespace

For more information about interaction requests and displaying notifications, see “MVVM Advanced Scenarios” in “Prism (Composite Application Guidance)” on MSDN (http://www.microsoft.com/prism).

The URL to the bibliography can be found in the preface, in the final section, entitled, “Where to Go for More Information.”

Prism Library for Windows Phone 7

Prism is a free utility library from the Microsoft® patterns & practices group. The components in this library can help developers build applications for Windows® Presentation Foundation (WPF), Microsoft Silverlight®, and the Windows Phone 7 platform that are easier to maintain and update as requirements change.

Prism was originally built to support composite application scenarios, where you might typically have a shell application and modules
that contribute pieces to the overall application. Although Prism supports this application style, most of the library components offered
by Prism can be useful in building any WPF or Silverlight application. For example, Prism offers components to support the Model-View-
ViewModel (MVVM) pattern as well as pieces to provide loosely coupled communication between parts of an application.

Although the use of a display shell is typically not appropriate in a Windows Phone 7 application, many of the other components
within Prism are useful when building Silverlight applications for Windows Phone 7. For example, you can use the DelegateCommand
provided by Prism to avoid the requirement to implement event handlers in the code-behind of your views when using the MVVM pattern
for your applications.

Prism includes a small library known as the Prism Library for Windows Phone 7, which contains a subset of the main Prism Library features specifically aimed at helping developers to implement solutions to common issues found in developing applications for Windows Phone 7. The library includes classes to help developers implement commands, navigation, observable object notifications, data template selection, interaction with notifications, interaction with the application bar, and more when building applications for Windows Phone 7.

This appendix provides an overview of the Prism Library for Windows Phone 7, which is used in the Tailspin application for Windows
Phone 7 discussed in this guide. For more information and to download Prism, see the Prism home page on MSDN® (http://www.microsoft.com/prism). To provide feedback, get assistance, or download additional content, visit the Prism community site on CodePlex (http://prism.codeplex.com).

Reactive Extensions

data, such as the Accelerometer or the Location Service, you must often manage multiple concurrent streams of information. Other
scenarios in which the same requirements occur are when composing information returned from multiple concurrent requests to remote services, or when you need to handle inputs such as recording sound. In addition, if you are building and testing applications using an emulator instead of a physical device, some of the device capabilities (such as the Accelerometer) are not available. In these situations, you may find the Reactive Extensions (Rx) for .NET feature useful.

The reactive extensions also allow you to write compact, declarative code to manage complex, asynchronous operations.

Reactive extensions allow you to do the following:

  • Represent data streams, asynchronous requests, and events as observable sequences to which applications and components can subscribe.
  • Compose multiple streams into a single stream.
  • Define queries that filter streams to select only specific data items.
  • Apply transformations to data streams.
  • Emulate data streams that are not available in the current environment (such as a device emulator).
  • Read and write the streams to storage on the device, and play them back when required.

The majority of operations you perform with reactive extensions are implemented by the Observable class, which exposes a large number
of methods for creating, merging, manipulating, and querying streams. For a full list of these methods, see “Observable Members” on MSDN (http://msdn.microsoft.com/en-us/library/microsoft.phone.reactive.observable_members(VS.92).aspx).

For more information about reactive streams, see “Reactive Extensions for .NET Overview for Windows Phone” (http://msdn.microsoft.
com/en-us/library/ff431792(VS.92).aspx) and “How to: Use Reactive Extensions to Emulate and Filter Location Data for Windows Phone” (http://msdn.microsoft.com/en-us/library/ff637517(VS.92).aspx) on MSDN. You can also download a code sample that demonstrates
using the reactive extensions from “Code Samples for Windows Phone” on MSDN (http://msdn.microsoft.com/en-us/library/ff431744(VS.92).aspx).

The URL to the bibliography can be found in the preface, in the final section, entitled, “Where to Go for More Information.”

Windows Marketplace

Windows Phone 7 devices obtain applications through the Windows Marketplace hub. This is available from the Start screen, but you can
invoke the hub in your code in a variety of ways. You can open the hub to show specific types of content such as applications, music, or podcasts. You can also open the hub showing a filtered list of items from one of these categories using a search string, or you can just show a specific item by specifying its GUID content identifier. Finally, you can open the Reviews screen.

The following code examples show how you can use the Windows Marketplace task launchers in your application code.

C#
// Open the Windows Marketplace hub to show all applications.
MarketplaceHubTask marketPlace = new MarketplaceHubTask();
marketPlace.ContentType = MarketplaceContentType.Applications;
// Other options are MarketplaceContentType.Music
// and MarketplaceContentType.Podcasts.
marketPlace.Show();
// —————————————————–
// Open the Windows Marketplace hub to search for
// applications using a specified search string.
MarketplaceSearchTask marketSearch = new MarketplaceSearchTask();
marketSearch.ContentType = MarketplaceContentType.Applications;
marketSearch.SearchTerms = “Tailspin Surveys”;
marketSearch.Show();
// —————————————————–
// Open the Windows Marketplace hub with a specific
// application selected for download and installation.
MarketplaceDetailTask marketDetail = new MarketplaceDetailTask();
marketDetail.ContentType = MarketplaceContentType.Applications;
marketDetail.ContentIdentifier
= “{12345678-1234-1234-1234-123456789abc}”;
marketDetail.Show();
// —————————————————–
// Open the Windows Marketplace hub Review page.
MarketplaceReviewTask marketReview = new MarketplaceReviewTask();
marketReview.Show();

If you call the Show method of the MarketplaceDetailTask class without specifying a value for the ContentIdentifier property, the
task will show the Windows Marketplace page for the current application.

For more information about the tasks described in this section, and the other types of tasks available on Windows Phone 7 devices, see “Microsoft.Phone.Tasks Namespace” on MSDN (http://msdn.microsoft.com/en-us/library/microsoft.phone.tasks(VS.92).aspx).

If you want to provide a link to a specific product on Windows Marketplace within a Web page or another application, you can do so
by specifying the appropriate product ID in the link. The following shows the format of a link to an application on Windows Marketplace.

http://social.zune.net/redirect?type=phoneApp&id=12345678-1234-1234-1234-123456789abc&source=MSDN

 

Vibration Alerts and Web Browser

Vibration Alerts

Application code can initiate the vibration capability of the device to alert users of events occurring in the application. To use this feature,
you must do the following:

  • Add a reference to the namespace Microsoft.Devices to your class.
  • Call the static methods of the default VibrateController class to start and stop vibration.

To initiate vibration for the default duration, call the Start method. To specify the duration, include a TimeSpan that defines the duration of the vibration as the parameter of the Start method. To stop vibration, call the Stop method.

C#
VibrateController.Default.Start(); // Default duration
VibrateController.Default.Start(TimeSpan.FromSeconds(2));
VibrateController.Default.Stop();

Web Browser

You can invoke the Windows Phone 7 web browser in your applications using the WebBrowserTask class. You simply specify the URL
to open, and call the Show method. The following code example shows how to do this.

C#
WebBrowserTask browserTask = new WebBrowserTask();
browserTask.URL = “http://www.microsoft.com/windowsmobile”;
browserTask.Show();

For more information, see “WebBrowserTask Class” on MSDN (http://msdn.microsoft.com/en-us/library/microsoft.phone.tasks.webbrowsertask(VS.92).aspx).

Touch and Gestures

In most cases, your application will use events exposed by the UI controls to detect user input, such as the Click event of a Button
control or the TextChanged event of a TextBox control. However, you can capture user touch and gestures directly if you want. This may
be useful for gestures such as drag, flick, and hold. Windows Phone 7 provides native support for gesture detection using both Silverlight
and XNA.

The TouchPanel class in the XNA Framework libraries is designed to provide advanced gesture detection capabilities for games and
other XNA-based interactive applications. You can use the XNA interop capabilities of Silverlight to implement gesture detection using
this approach if you want.

However, for a Silverlight application, you can take advantage of two other simpler approaches to gesture detection. You can use the
built-in manipulation mechanism for Silverlight controls, or you can install and use the GestureListener control that is included in the
Silverlight for Windows Phone Toolkit.

The following table provides a comparison of the approaches you can use.

provides a comparison of the approaches

Gesture Detection using Silverlight Manipulation Events

The Windows Phone page and most of the UI controls automatically support manipulation events. You can detect manipulation at the individual control level, or for the page as a whole, by handling the three events that occur when manipulation of the control or page starts,
each time a movement (a delta) is detected, and when the manipulation ends.

The following code example shows how you can wire up handlers for the three manipulation events of the page.

C#
public MainPage()
{
InitializeComponent();
this.ManipulationStarted +=
this.PhoneApplicationPage_ManipulationStarted;
this.ManipulationDelta +=
this.PhoneApplicationPage_ManipulationDelta;
this.ManipulationCompleted +=
this.PhoneApplicationPage_ManipulationCompleted;
}

Each of these events passes a specific type of argument class to the handler. You can extract the values from the arguments to detect
the type of movement and the values, as shown in the following code example. Scale values are generated by pinch or stretch gestures and
are generally used to resize objects. Translation values are generated by movement over the screen, and are generally used to move objects.

C#
// Raised when the gesture starts. Typically used only to detect
// tap events, or to start a timer if you want to differentiate
// tap and double-tap events.
void PhoneApplicationPage_ManipulationStarted(object sender,
ManipulationStartedEventArgs e)
{
double xStartCoordinate = e.ManipulationOrigin.X;
double yStartCoordinate = e.ManipulationOrigin.Y;
}
// Raised repeatedly during the gesture. Can be used to
// provide dynamic visual feedback to the user.
void PhoneApplicationPage_ManipulationDelta(object sender,
ManipulationDeltaEventArgs e)
{
double xScale = e.DeltaManipulation.Scale.X;
double yScale = e.DeltaManipulation.Scale.Y;
double xTranslation = e.DeltaManipulation.Translation.X;
double yTranslation = e.DeltaManipulation.Translation.Y;
}
// Raised when the gesture ends. The original start position
// is available as well as the relative scale and translation
// values and information about the gesture velocities.
void PhoneApplicationPage_ManipulationCompleted(object sender,
ManipulationCompletedEventArgs e)
{
double xStartOrigin = e.ManipulationOrigin.X;
double yStartOrigin = e.ManipulationOrigin.Y;
double xTotalScale = e.TotalManipulation.Scale.X;
double yTotalScale = e.TotalManipulation.Scale.Y;
double xTotalTranslation = e.TotalManipulation.Translation.X;
double yTotalTranslation = e.TotalManipulation.Translation.Y;
double xExpansionVelocity =
e.FinalVelocities.ExpansionVelocity.X;
double yExpansionVelocity =
e.FinalVelocities.ExpansionVelocity.Y;
double xLinearVelocity = e.FinalVelocities.LinearVelocity.X;
double yLinearVelocity = e.FinalVelocities.LinearVelocity.Y;
}

For more information about using the Silverlight manipulation events, see “Gesture Support for Windows Phone” (http://msdn.
microsoft.com/en-us/library/ff967546(VS.92).aspx) and “How to: Handle Manipulation Events” (http://msdn.microsoft.com/en-us/library/ff426933(VS.95).aspx) on MSDN.

Gesture Detection Using the GestureListener Control

If you simply need to detect the full range of gestures and the basic position, scale, and translation information, you should consider using
the GestureListener control that is included in the Silverlight for Windows Phone Toolkit. This control makes it easy to handle the full range of gesture events, including Tap, Double-tap, Hold, Drag, Flick, and Pinch. You can obtain the Silverlight for Windows Phone Toolkit
from the Silverlight Toolkit website on CodePlex (http://silverlight.codeplex.com/).

To use the GestureListener control, you must reference the assembly Microsoft.Phone.Controls.Toolkit in your project and add
the control to a page in your application. The following example shows the control inserted into a Grid that covers the complete page,
except for the page title area.

XAML

<Grid x:Name=”ContentPanel” Grid.Row=”1″ Margin=”12,0,12,0″
Background=”Black”>
<Grid.OpacityMask>
<SolidColorBrush />
</Grid.OpacityMask>
<toolkit:GestureService.GestureListener>
<toolkit:GestureListener
Tap=”OnTap”
DoubleTap=”OnDoubleTap”
Hold=”OnHold”
DragStarted=”OnDragStarted”
DragDelta=”OnDragDelta”
DragCompleted=”OnDragCompleted”
Flick=”OnFlick”
PinchStarted=”OnPinchStarted”
PinchDelta=”OnPinchDelta”
PinchCompleted=”OnPinchCompleted”/>
</toolkit:GestureService.GestureListener>
</Grid>

Notice that the properties of the GestureListener allow you to specify individual event handlers for each detected event. The
GestureListener control effectively wraps the XNA gesture detection mechanism and performs automatic conversion of the XNA
events into individual Silverlight events for each gesture type.

The following code example shows the event handlers and the values you can obtain for each type of event detected by the control.
Note that the control may raise a combination of events for some gestures. For example, it may raise the Drag events during a flick gesture
and when the flick gesture completes.

C#
private void OnTap(object sender, GestureEventArgs e)
{
// Get the screen position relative to the page.
double xPosition = e.GetPosition(this).X;
double yPosition = e.GetPosition(this).Y;
}
private void OnDoubleTap(object sender, GestureEventArgs e)
{
double xPosition = e.GetPosition(this).X;
double yPosition = e.GetPosition(this).Y;
}
private void OnHold(object sender, GestureEventArgs e)
{
double xPosition = e.GetPosition(this).X;
double yPosition = e.GetPosition(this).Y;
}
// This is raised when a drag gesture starts.
private void OnDragStarted(object sender,
DragStartedGestureEventArgs e)
{
double xPosition = e.GetPosition(this).X;
double yPosition = e.GetPosition(this).Y;
}
// This is raised repeatedly during a drag gesture.
private void OnDragDelta(object sender, DragDeltaGestureEventArgs e)
{
double xOriginalPosition = e.GetPosition(this).X;
double yOriginalPosition = e.GetPosition(this).Y;
double xMovement = e.HorizontalChange;
double yMovement = e.VerticalChange;
}
// This is raised when a drag gesture completes.
private void OnDragCompleted(object sender,
DragCompletedGestureEventArgs e)
{
double xOriginalPosition = e.GetPosition(this).X;
double yOriginalPosition = e.GetPosition(this).Y;
double xMovement = e.HorizontalChange;
double yMovement = e.VerticalChange;
double xVelocity = e.HorizontalVelocity;
double yVelocity = e.VerticalVelocity;
}
// This is raised in conjunction with Drag events
// after a flick gesture completes.
private void OnFlick(object sender, FlickGestureEventArgs e)
{
double xPosition = e.GetPosition(this).X;
double yPosition = e.GetPosition(this).Y;
double angle = e.Angle;
double xVelocity = e.HorizontalVelocity;
double yVelocity = e.VerticalVelocity;
}
// This is raised when a pinch or zoom gesture starts.
private void OnPinchStarted(object sender,
PinchStartedGestureEventArgs e)
{
double xPosition = e.GetPosition(this).X;
double yPosition = e.GetPosition(this).Y;
double distance = e.Distance;
double angle = e.Angle;
}
// This is raised repeatedly during a pinch or zoom gesture.
private void OnPinchDelta(object sender, PinchGestureEventArgs e)
{
double xOriginalPosition = e.GetPosition(this).X;
double yOriginalPosition = e.GetPosition(this).X;
double distance = e.DistanceRatio;
double angle = e.TotalAngleDelta;
}
// This is raised when a pinch or zoom gesture completes.
private void OnPinchCompleted(object sender,
PinchGestureEventArgs e)
{
double xOriginalPosition = e.GetPosition(this).X;
double yOriginalPosition = e.GetPosition(this).X;
double distance = e.DistanceRatio;
double angle = e.TotalAngleDelta;
}

For more information and to download the Silverlight for Windows Phone Toolkit, see the Silverlight Toolkit page on CodePlex (http://silverlight.codeplex.com/).

Gesture Detection Using XNA

To detect touch and gestures using the XNA Framework classes, you must do the following:

  • Add a reference to the assemblies Microsoft.Xna.Framework and Microsoft.Xna.Framework.Input.Touch to your project.
  • Set the properties of the static TouchPanel class to specify the types of gestures you want to capture.
  • Start a DispatcherTimer that will raise an event at appropriate intervals.
  • Handle the event raised by the DispatcherTimer to obtain the gesture information.

The following code example specifies that the TouchPanel will collect all gestures except for horizontal drag and vertical drag (which
constrain the results in one direction). It then creates a Dispatcher Timer with an interval of 50 milliseconds, though you can vary this
depending on how often you want to read gesture information, adds the event handler, and starts the timer. To use this code, you must
reference the namespace System.Windows.Threading.

C#
TouchPanel.DisplayHeight = 800;
TouchPanel.DisplayWidth = 480;
TouchPanel.EnabledGestures = GestureType.Tap |
GestureType.DoubleTap |
GestureType.Hold |
GestureType.FreeDrag |
GestureType.Flick |
GestureType.Pinch;
var touchTimer = new DispatcherTimer();
touchTimer.Interval = TimeSpan.FromMilliseconds(50);
touchTimer.Tick += new EventHandler(Read_Gestures);
touchTimer.Start();

In the event raised by the timer, you can read each gesture. However, each gesture will consist of several individual components; for
example, a double tap will result in detection of both a tap and a double tap gesture, so your code must examine the sequence of gestures
to determine what action to take.

The following code example of a gesture detection event handler shows how you obtain information about each gesture that was detected.
It indicates the values that are available for each of the gesture types. Remember that the event handler runs on a different thread from the UI, so you must invoke a method on the UI thread if you want to update the UI with the discovered values.

C#
public void Read_Gestures(object sender, EventArgs e)
{
float xCoordinate = 0;
float yCoordinate = 0;
float xStartCoordinate = 0;
float yStartCoordinate = 0;
float xEndCoordinate = 0;
float yEndCoordinate = 0;
float xSecondFingerStartCoordinate = 0;
float ySecondFingerStartCoordinate = 0;
float xSecondFingerEndCoordinate = 0;
float ySecondFingerEndCoordinate = 0;
float xFlickSpeed = 0;
float yFlickSpeed = 0;
while (TouchPanel.IsGestureAvailable)
{
GestureSample gesture = TouchPanel.ReadGesture();
switch (gesture.GestureType)
{
case GestureType.Tap:
xCoordinate = gesture.Position.X;
yCoordinate = gesture.Position.Y;
break;
case GestureType.DoubleTap:
xCoordinate = gesture.Position.X;
yCoordinate = gesture.Position.Y;
break;
case GestureType.Hold:
xCoordinate = gesture.Position.X;
yCoordinate = gesture.Position.Y;
break;
case GestureType.FreeDrag:
xEndCoordinate = gesture.Position.X;
yEndCoordinate = gesture.Position.Y;
xStartCoordinate = xEndCoordinate – gesture.Delta.X;
yStartCoordinate = yEndCoordinate – gesture.Delta.Y;
// For GestureType.HorizontalDrag, Delta.Y
// will always be zero.
// For GestureType.VerticalDrag, Delta.X
// will always be zero.
break;
case GestureType.Flick:
xFlickSpeed = gesture.Delta.X; // pixels per second
yFlickSpeed = gesture.Delta.Y; // pixels per second
break;
case GestureType.Pinch:
xEndCoordinate = gesture.Position.X;
yEndCoordinate = gesture.Position.Y;
xStartCoordinate = xEndCoordinate – gesture.Delta.X;
yStartCoordinate = yEndCoordinate – gesture.Delta.Y;
xSecondFingerStartCoordinate = gesture.Position2.X;
ySecondFingerStartCoordinate = gesture.Position2.Y;
xSecondFingerEndCoordinate = xSecondFingerStartCoordinate
– gesture.Delta2.X;
ySecondFingerEndCoordinate = ySecondFingerStartCoordinate
– gesture.Delta2.Y;
break;
}
}
}

For more information about using XNA to detect gestures, see “Working with Touch Input (Windows Phone)” on MSDN (http://
msdn.microsoft.com/en-us/library/ff434208.aspx).

Sound Recording

All Windows Phone 7 physical devices include a microphone. You can access this using the methods of the XNA Framework. This is more complex than using some other features of the phone because you must initiate an asynchronous dispatcher to raise the microphone events.

To record sounds from the microphone, you must do the following:

  • Add a reference to the assembly Microsoft.Xna.Framework to your project.
  • Create an XNA asynchronous dispatcher “pump” class and initialize it in the constructor or startup event in your App.xaml. cs file.
  • Get a reference to a microphone.
  • Specify a function or lambda expression that will receive the sound data.
  • Start the microphone.

Note: An XNA asynchronous event dispatcher is an application service that allows Silverlight to detect events raised by XNA components. Usually, these events are propagated by the XNA game loop mechanism, but this is not present in a Silverlight application. The dispatcher service collects these events and raises them through the Silverlight event mechanism.

In your application, declare variables to hold the microphone instance and a stream that will receive the sound data bytes. This example uses the default microphone and an isolated storage file stream. To use this code, you must reference the namespaces Microsoft.Xna. Framework.Audio and System.IO.IsolatedStorage.

C#
Microphone mic = Microphone.Default;
IsolatedStorageFileStream myFileStream;

Specify the callback for the BufferReady event and the size of the recording buffer. The maximum size is one second, though lower values tend to give better performance.

C#
mic.BufferReady += Mic_BufferReady;
mic.BufferDuration = TimeSpan.FromMilliseconds(500);

Open the file stream that will receive the recorded data (in this case, an isolated storage file), and then start the microphone to begin recording.

C#
// Create a virtual store and file stream.
// Check for an existing duplicate name.
var myStore = IsolatedStorageFile.GetUserStoreForApplication();
String fileName = “MyAudio.dat”;
if (myStore.FileExists(fileName))
{
myStore.DeleteFile(fileName);
}
myFileStream = myStore.CreateFile(fileName);
mic.Start();

The callback for the BufferReady event must capture the data from the microphone and store it in your target location.

C#
void Mic_BufferReady(object sender, EventArgs e)
{
Microphone mic = sender as Microphone;
byte[] content = new byte[mic.GetSampleSizeInBytes
(mic.BufferDuration)];
mic.GetData(content);
myFileStream.Write(content, 0, content.Length);
}

To stop recording, call the Stop method of the Microphone class and close the stream you are writing to.

C#
mic.Stop();
myFileStream.Close();

You can check the status of the microphone at any time by querying the State property of the Microphone class. This returns a value from the MicrophoneState enumeration. Possible values are Started and Stopped.

For more information, see “Microphone Class” on MSDN (http://msdn.microsoft.com/en-us/library/microsoft.xna.framework.audio.microphone(XNAGameStudio.40).aspx).

Note: The files created from the byte stream returned by the Microphone class are not valid sound files. If you want to convert a saved byte stream as a .wav or .wmv file, you must use an auxiliary class or library to add the appropriate headers to the file and save it is the appropriate format. For a description of the .wav file format, see “Wave File Format” on The Sonic Spot website (http://www.sonicspot.com/guide/wavefiles.html).

The following series of posts by Microsoft academic developer evangelist Dan Waters describe the techniques of audio programming and provide code you can reuse:

“Intro to Audio Programming, Part 1: How Audio Data is Represented” at http://blogs.msdn.com/b/dawate/archive/2009/06/22/intro-to-audio-programming-part-1-howaudio-data-is-represented.aspx

“Intro to Audio Programming, Part 2: Demystifying the WAV Format” at http://blogs.msdn.com/b/dawate/archive/2009/06/23/intro-to-audio-programming-part-2-demystifying-the-wav-format.aspx

“Intro to Audio Programming, Part 3: Synthesizing Simple Wave Audio using C#” at http://blogs.msdn.com/b/dawate/archive/2009/06/24/intro-to-audio-programming-part-3-synthesizing-simple-wave-audio-using-c.aspx

“Intro to Audio Programming Part 4: Algorithms for Different Sound Waves in C#” at http://blogs.msdn.com/b/dawate/archive/2009/06/25/intro-to-audio-programming-part-4-algorithms-
for-different-sound-waves-in-c.aspx

 

 

The Bing Maps Silverlight Control

Alternatively, for a more immersive experience, you can use the Bing Maps Silverlight Control for Windows Phone. This control allows users to search for locations and interact with the map using tap, stretch, pinch, and pan gestures. It also gives you a great deal of control over how the map is displayed, the centered location, the view it displays (such as Aerial, Birdseye, or Road), the zoom level, and much more. In addition, you can handle events exposed by the control within your
application to interact with the user if required.

Note: You must register and obtain a key from the Bing Maps Account Center from the Bing page on Microsoft.com (http://www.microsoft.com/maps/developers/) in order to use Bing Maps in your applications. If you do not specify a valid key for the Bing Maps control in your application, it displays a message that the credentials are invalid.

As an example, if you have established the current location of the device using a GeoCoordinateWatcher, as described earlier in this section, you can display a map using the Bing Maps control embedded in a page of your application. The following code example sets the properties of a Bing Maps control to display a specific location. It sets the zoom level to 12 and displays the controls for zooming in and out and the scale indicator.

C#
Location loc = new Location();
loc.Latitude = watcher.Position.Location.Latitude;
loc.Longitude = watcher.Position.Location.Longitude;
loc.Altitude = watcher.Position.Location.Altitude;
double zoom = 12.0;
myMapControl.ScaleVisibility = System.Windows.Visibility.Visible;
myMapControl.ZoomBarVisibility = Visibility.Visible;
myMapControl.SetView(loc, zoom);

To use the Bing Maps control, you must reference the corresponding namespaces in your application. The minimum set is Microsoft. Phone.Controls.Maps, Microsoft.Phone.Controls.Maps.Design, and Microsoft.Phone.Controls.Maps.Platform. If you use the extended features of the MapCore class that implements the Bing Maps control, you may also require the namespaces Microsoft.Phone. Controls.Maps.AutomationPeers, Microsoft.Phone.Controls.Maps.Core, and Microsoft.Phone.Controls.Maps.Overlays.

For more information about using the Bing Maps control to provide an interactive mapping experience for users of your application, see “Bing Maps Silverlight Control for Windows Phone” on MSDN (http://msdn.microsoft.com/en-us/library/ff941096(VS.92).aspx).