Статьи

WP к W8: сопоставление API

Эта статья является частью серии о моем опыте портирования приложений с Windows Phone на Windows 8. Официальное руководство по портированию можно найти здесь, и не забывайте следить за блогом Building Windows 8 и блогом разработчиков приложений для Windows 8 для получения последней информации.

Эта статья будет тем, что мой коллега и друг Райан Лоудермилк любит называть «частью SEO». Райан имеет в виду, что, хотя он может и не облегчить чтение с кресла, он по-прежнему будет отвечать потребностям тех, кто ищет определенную часть информации. В этой статье рассказывается о том, как часто используемые API-интерфейсы Windows Phone и функции XAML сопоставляются (или не сопоставляются) со своими аналогами в Windows 8.

В этой статье не будет много диалогов. Я расскажу, для чего используется API, покажу версию Windows Phone и покажу версию Windows 8. Если есть какие-то важные трюки, которые я хочу отметить, я тоже перечислю их.

Пространства имен XAML

Как упоминалось в первом посте, пространства имен объявляются по-разному.

WP – xmlns:imgsch="clr-namespace:ImageSearch;assembly=…"

W8 – xmlns:imgsch="using:ImageSearch" 

Мы изменяем clr-namespace: for using: и нам больше не нужно указывать имя сборки. Это хорошо, потому что пространство имен разрешается в разных сборках, поэтому нам не нужно иметь несколько объявлений пространства имен, если одно и то же пространство имен используется в нескольких библиотеках.

Константы XAML

Собственные типы (string, int) находятся в другом пространстве имен:

WP – <sys:String x:Key="AppName">Foo</sys:String>

W8 – <x:String x:Key="AppName">Foo</x:String>

Эти типы констант редко используются в Xaml, но они пригодятся для многоразовых строк, таких как имя приложения. Просто помните, что в Windows 8 вы используете префикс x: для этих типов.

Сенсорный ввод

Windows 8 имеет единую систему ввода и больше не поддерживает специфичные для мыши события:

WP – MouseLeftButtonUp="eventhandler"

W8 – PointerReleased="eventhandler"

EventHandler выше будет вызываться всякий раз , когда пользователь отпускает правую кнопку мыши, поднимает палец от дисплея или удаляет перо с поверхности. Все три устройства ввода считаются «указателями», и каждый «указатель» может отслеживаться индивидуально при желании.

Еще лучше рассмотреть возможность использования нового жеста и события Item:

W8 – Tapped="eventhandler"

W8 – ItemClick="eventhandler"

Note: Don’t forget IsItemClickEnabled="True"

События Item, такие как ItemClick , особенно ценны, потому что вы знаете, что a) элемент был фактически нажат и b) какой это был элемент. Это намного лучше, чем пытаться использовать событие SelectionChanged или LeftMouseButtonUp и проверять свойство SelectedItem .

Изменения в обработчике событий

RoutedEventArgs по-прежнему используется для большинства событий управления, таких как нажатие кнопки. Однако RoutedEventArgs теперь находится в другом пространстве имен (и вам придется изменить его в своем коде позади):

WP – System.Windows.RoutedEventArgs

W8 – Windows.UI.Xaml.RoutedEventArgs

Так как события мыши исчезли, MouseButtonEventArgs тоже. События мыши продаются для событий жестов или указателей:

WP – System.Windows.Input.MouseButtonEventArgs

W8 – Windows.UI.Xaml.Input.TappedRoutedEventArgs

W8 – Windows.UI.Xaml.Input.PointerRoutedEventArgs

навигация

В Windows Phone мы переходим к Uri и передаем любые параметры как часть строки запроса. В Windows 8 мы переходим к типу страницы, и параметры можно передавать как целые объекты.

Windows Phone 7

NavigationService.Navigate(new Uri("/DetailsPage.xaml?Id=5", UriKind.Relative));
Windows 8

Frame.Navigate(typeof(DetailsPage), e.ClickedItem);

Настройки хранения — Локальные

Как Windows Phone, так и Windows 8 предоставляют способ хранения настроек приложения между запусками на одном устройстве.

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";

Хранение настроек — роуминг

Windows 8 предоставляет способ хранения настроек приложения, которые будут синхронизироваться между устройствами пользователей. Для получения дополнительной информации см. Рекомендации по перемещению данных приложения .

Windows Phone 7

Not an option

 

Windows 8

settings = ApplicationData.Current.RoamingSettings;

 

// The rest is the same as local settings

Хранение файлов — локально

Как Windows Phone, так и Windows 8 предоставляют способ хранения файлов, принадлежащих приложению.

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");

Хранение файлов — роуминг

Windows 8 предоставляет папку для файлов, которые будут автоматически синхронизироваться между устройствами пользователей. Для получения дополнительной информации см. Рекомендации по перемещению данных приложения .

Windows Phone 7

Not an option
Windows 8

folder = ApplicationData.Current.RoamingFolder;

// The rest is the same as a local file

Хранение файлов — временное

В Windows 8 предусмотрена папка для файлов, которые будут автоматически удалены при выполнении задачи обслуживания системы.

Windows Phone 7

Not an option
Windows 8

folder = ApplicationData.Current.TemporaryFolder;

 

// The rest is the same as a local file

Создание вторичной плитки

Как Windows Phone, так и Windows 8 предлагают вторичные плитки, но они создаются и обновляются по-разному.

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();

Обновление основной плитки

Важное замечание : В Windows 8 плитки создаются с использованием XML, а не классов. Microsoft создала вспомогательные классы для работы с плитками как объектами вместо XML. Эти вспомогательные классы включены в образец плиток и значков приложения . Код Windows 8 ниже использует эти вспомогательные классы.

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());

Обновление вторичной плитки

Важное замечание : В Windows 8 плитки создаются с использованием XML, а не классов. Microsoft создала вспомогательные классы для работы с плитками как объектами вместо XML. Эти вспомогательные классы включены в образец плиток и значков приложения . Код Windows 8 ниже использует эти вспомогательные классы.

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

Тосты

Важное замечание : В Windows 8 тосты создаются с использованием XML, а не классов. Microsoft создала вспомогательные классы для работы с тостами как объектами вместо XML. Эти вспомогательные классы включены в пример уведомлений Toast . Код Windows 8 ниже использует эти вспомогательные классы.

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());

Место нахождения

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)

{

…

}

акселерометр

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)

{

…

}

Открыть фото

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)

{

…

}

Захватить фото

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)

{

…

}

Захват видео — интерфейс системы

В Windows Phone 7 отсутствует системный пользовательский интерфейс для захвата видео (хотя пользовательский интерфейс может быть создан). В Windows 8 системный интерфейс может использоваться для захвата файлов MP4 и WMV.

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)

{

…

}

Захват видео — пользовательский интерфейс

Пользовательский захват видео на обеих платформах включает в себя размещение на экране элемента, который будет отображать предварительный просмотр видео, создание устройства захвата, подключение визуального элемента к устройству захвата и захват видео в целевой файл.

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);