WP to W8: API Mapping
This article is part of a series about my experience porting apps from Windows Phone to Windows 8. Official porting guidance can be found here and don’t forget to follow the Building Windows 8 blog and the Windows 8 App Developer blog for the latest information.
This article will be what my co-worker and friend Ryan Lowdermilk likes to refer to as a “SEO piece”. What Ryan means is while it may not make for easy chair reading, it will still meet a need for those searching for a particular piece of information. The information in this article is how commonly used Windows Phone APIs and XAML features map (or do not map) to their Windows 8 counterparts.
There won’t be a lot of dialog in this article. I’ll mention what the API is used for, show the Windows Phone version and show the Windows 8 version. If there are any important tricks to note, I’ll list those too.
XAML Namespaces
As mentioned in the first post, namespaces are declared differently
WP – xmlns:imgsch="clr-namespace:ImageSearch;assembly=…" W8 – xmlns:imgsch="using:ImageSearch"
We change clr-namespace: for using: and we no longer have to specify the assembly name. This is nice because the namespace is resolved across assemblies, so we don’t have to have multiple namespace declaration if the same namespace is used in multiple dlls.
XAML Constants
Native Types (string, int) are in a different namespace:
WP – <sys:String x:Key="AppName">Foo</sys:String> W8 – <x:String x:Key="AppName">Foo</x:String>
These kinds of constants are rarely used in Xaml, but they do come in handy for reusable strings like the application name. Just be aware that in Windows 8 you use the x: prefix for these types.
Touch Input
Windows 8 has a unified input system and no longer supports mouse-specific events:
WP – MouseLeftButtonUp="eventhandler" W8 – PointerReleased="eventhandler"
The eventhandler above would get called whenever the user releases the right mouse button, raises their finger off the display or removes the pen from the surface. All three input devices are considered “pointers” and each “pointer” can be tracked individually if desired.
Even better, consider using the new gesture and Item events:
W8 – Tapped="eventhandler" W8 – ItemClick="eventhandler" Note: Don’t forget IsItemClickEnabled="True"
The Item events like ItemClick are especially valuable because you know that a) an item was actually tapped and b) which item it was. This is so much better than trying to use the SelectionChanged event or LeftMouseButtonUp and checking the SelectedItem property.
Event Handler Changes
RoutedEventArgs is still used for most control events like button click. However, RoutedEventArgs is now in a different namespace (and you’ll have to change it in your code behind):
WP – System.Windows.RoutedEventArgs W8 – Windows.UI.Xaml.RoutedEventArgs
Since mouse events are gone,MouseButtonEventArgs is too. Mouse events are traded for gesture or pointer events:
WP – System.Windows.Input.MouseButtonEventArgs W8 – Windows.UI.Xaml.Input.TappedRoutedEventArgs W8 – Windows.UI.Xaml.Input.PointerRoutedEventArgs
Navigation
On Windows Phone we navigate to a Uri and we pass any parameters as part of the query string. On Windows 8 we navigate to the Type of the page and parameters can be passed as whole objects.
Windows Phone 7
NavigationService.Navigate(new Uri("/DetailsPage.xaml?Id=5", UriKind.Relative));Windows 8 Frame.Navigate(typeof(DetailsPage), e.ClickedItem);
Storing Settings – Local
Both Windows Phone and Windows 8 provide a way to store application settings between runs on the same device.
Windows Phone 7 settings = IsolatedStorageSettings.ApplicationSettings; settings["exampleSetting"] = "Hello Phone";
Windows 8 settings = ApplicationData.Current.LocalSettings; container = settings.CreateContainer(“main", ApplicationDataCreateDisposition.Always); settings.Containers["main"].Values["exampleSetting"] = "Hello Windows";
Storing Settings – Roaming
Windows 8 provide a way to store application settings that will get synchronized across the users devices. For more information see Guidelines for roaming application data.
Windows Phone 7 Not an option
Windows 8 settings = ApplicationData.Current.RoamingSettings; // The rest is the same as local settings
Storing Files – Local
Both Windows Phone and Windows 8 provide a way to store files that belong to the application
Windows Phone 7
using (var store = IsolatedStorageFile.GetUserStoreForApplication())
{
store.CreateDirectory("SampleDirectory");
rootFile = store.CreateFile("SampleFile.txt"); // Open stream
rootFile.Close(); // Stream must be closed
}Windows 8
folder = ApplicationData.Current.LocalFolder;
// This is a StorageFile. It is not open.
file = await folder.CreateFileAsync("SampleFile.txt", CreateCollisionOption.ReplaceExisting);
// Writes text and closes file in one line
await FileIO.WriteTextAsync(file, "Hello World");Storing Files – Roaming
Windows 8 provide a folder for files that will automatically get synchronized across the users devices. For more information see Guidelines for roaming application data.
Windows Phone 7 Not an option
Windows 8 folder = ApplicationData.Current.RoamingFolder; // The rest is the same as a local file
Storing Files – Temporary
Windows 8 provide a folder for files that will automatically get deleted by the system maintenance task.
Windows Phone 7 Not an option
Windows 8 folder = ApplicationData.Current.TemporaryFolder; // The rest is the same as a local file
Creating a Secondary Tile
Both Windows Phone and Windows 8 offer secondary tiles, but they are created and updated in different ways.
Windows Phone 7
tileData = new StandardTileData
{
// Set tile data
}
ShellTile.Create(new Uri("/ItemDetail.xaml?Id=123", UriKind.Relative), tileData);Windows 8
tile = new SecondaryTile(
tileId, // Tile ID
shortTitle, // Tile short name
title, // Tile display name
"Id=123", // Activation argument
TileOptions.ShowNameOnLogo, // Tile options
"ms-appx:///images/someImage.png" // Tile logo
);
tile.RequestCreateAsync();Updating the Primary Tile
Important: On Windows 8, tiles are created using XML instead of classes. Microsoft has created helper classes to work with tiles as objects instead of XML. These helper classes are included in the App tiles and badges sample. The Windows 8 code below leverages these helper classes.
Windows Phone 7
tile = ShellTile.ActiveTiles.First();
if (tile != null)
{
tileData = new StandardTileData
{
// Set tile data
}
tile.Update(tileData);
}Windows 8 wide = TileContentFactory.CreateTileWideImageAndText01(); square = TileContentFactory.CreateTileSquareImage(); wide.SquareContent = squareContent; // Set wide and square tile data wide.TextCaptionWrap.Text = "This tile uses images"; wide.Image.Src = "ms-appx:///images/redWide.png"; square.Image.Src = "ms-appx:///images/graySquare.png"; // Update TileUpdateManager.CreateTileUpdaterForApplication().Update(wide.CreateNotification());
Updating the Secondary Tile
Important: On Windows 8, tiles are created using XML instead of classes. Microsoft has created helper classes to work with tiles as objects instead of XML. These helper classes are included in the App tiles and badges sample. The Windows 8 code below leverages these helper classes.
Windows Phone 7
tile = ShellTile.ActiveTiles.FirstOrDefault(<LINQ Query>);
if (tile != null)
{
tileData = new StandardTileData
{
// Set tile data
}
tile.Update(tileData);
}Windows 8 wide = TileContentFactory.CreateTileWideImageAndText01(); square = TileContentFactory.CreateTileSquareImage(); wide.SquareContent = squareContent; // Set wide and square tile data wide.TextCaptionWrap.Text = "This tile uses images"; wide.Image.Src = "ms-appx:///images/redWide.png"; square.Image.Src = "ms-appx:///images/graySquare.png"; // Update TileUpdateManager.CreateTileUpdaterForSecondaryTile(tileId).Update(wide.CreateNotificatio
Toasts
Important: On Windows 8, toasts are created using XML instead of classes. Microsoft has created helper classes to work with toasts as objects instead of XML. These helper classes are included in the Toast notifications sample. The Windows 8 code below leverages these helper classes.
Windows Phone 7
var toast = new ShellToast
{
Title = "Title",
Content = "Toast content",
NavigationUri = new Uri("ItemDetail.xaml?Id=123", UriKind.Relative)
};
toast.Show();Windows 8 toast = ToastContentFactory.CreateToastImageAndText02(); toast.TextHeading.Text = "Heading text"; toast.TextBodyWrap.Text = "Body text that wraps."; toast.Launch = “Id=123"; toast.Image.Src = "ms-appx:///images/graySquare.png"; ToastNotificationManager.CreateToastNotifier().Show(toast.CreateNotification());
Location
Windows Phone 7
watcher = new GeoCoordinateWatcher();
watcher.PositionChanged += watcher_PositionChanged;
watcher.TryStart(false, TimeSpan.FromMilliseconds(2000));
// Handler
private void watcher_PositionChanged(object sender, GeoPositionChangedEventArgs<GeoCoordinate> e)
{
…
}Windows 8
locator = new Geolocator();
locator.PositionChanged += locator_PositionChanged;
// Handler
private void locator_PositionChanged(Geolocator sender, PositionChangedEventArgs e)
{
…
}Accelerometer
Windows Phone 7
accelerometer = new Accelerometer();
accelerometer.ReadingChanged += ReadingChanged;
// Handler
private void ReadingChanged(object sender, AccelerometerReadingEventArgs e)
{
…
}Windows 8
accelerometer = Accelerometer.GetDefault();
if (accelerometer != null)
{
accelerometer.ReadingChanged += ReadingChanged;
}
// Handler
private void ReadingChanged(object sender, AccelerometerReadingChangedEventArgs e)
{
…
}Open Photo
Windows Phone 7
chooser = new PhotoChooserTask();
chooser.Completed += chooser_Completed;
void chooser_Completed(object sender, PhotoResult e)
{
if (e.TaskResult == TaskResult.OK)
{
BitmapImage bmp = new BitmapImage();
bmp.SetSource(e.ChosenPhoto);
}
}Windows 8
var picker = new FileOpenPicker();
picker.ViewMode = PickerViewMode.Thumbnail;
picker.SuggestedStartLocation = PickerLocationId.PicturesLibrary;
picker.FileTypeFilter.Add(".jpg");
var file = await picker.PickSingleFileAsync();
if (file != null)
{
…
}Capture Photo
Windows Phone 7
chooser = new CameraCaptureTask ();
chooser.Completed += chooser_Completed;
void chooser_Completed(object sender, PhotoResult e)
{
if (e.TaskResult == TaskResult.OK)
{
BitmapImage bmp = new BitmapImage();
bmp.SetSource(e.ChosenPhoto);
}
}Windows 8
var camera = new CameraCaptureUI();
var file = await camera.CaptureFileAsync(CameraCaptureUIMode.Photo);
if (file != null)
{
…
}Capture Video – System UI
On Windows Phone 7 there is no system-provided UI for capturing video (though a custom UI can be created). On Windows 8, the system UI can be used to capture MP4 and WMV files.
Windows Phone 7 Not an option
Windows 8
CameraCaptureUI camera = new CameraCaptureUI();
camera.VideoSettings.Format = CameraCaptureUIVideoFormat.Mp4;
StorageFile file = await camera.CaptureFileAsync(CameraCaptureUIMode.Video);
if (file != null)
{
…
}Capture Video – Custom UI
Custom video capture on both platforms involves placing an element on the screen that will display the video preview, creating a capture device, connecting the visual element with the capture device, and capturing the video to a target file.
Windows Phone 7 videoCaptureDevice = CaptureDeviceConfiguration.GetDefaultVideoCaptureDevice(); captureSource = new CaptureSource(); fileSink = new FileSink(); fileSink.IsolatedStorageFileName = "CameraMovie.mp4"; fileSink.CaptureSource = captureSource; videoBrush.SetSource(captureSource); viewfinderRectangle.Fill = videoBrush; captureSource.Start();
Windows 8
mediaCapture = new MediaCapture();
await mediaCapture.InitializeAsync();
previewElement.Source = mediaCapture;
storageFile = await KnownFolders.VideosLibrary.CreateFileAsync("CameraMovie.mp4");
profile = MediaEncodingProfile.CreateMp4(VideoEncodingQuality.Auto);
await mediaCapture.StartRecordToStorageFileAsync(profile, storageFile);
(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)





