Windows 8 и Windows Phone 8 находятся на пути к слиянию. Тем временем, разработчики, заинтересованные в создании приложений для обеих платформ, должны хорошо понимать основные сходства и различия между этими платформами. Изучение того, в чем сейчас пересекаются Windows 8 и Windows Phone Runtime API, дает вам лучшую возможность поставлять приложения для обеих ОС, используя во многом те же знания, инструменты, код и ресурсы. В этой статье я исследую их различия и сходства; это поможет вам понять, что можно и что невозможно до того, как вы приступите к созданию решения, ориентированного на обе платформы.
Согласованность в UI — применение плиток, функциональный сенсорный интерфейс, панель приложения и принципы навигации — упрощают проектирование и реализацию приложений для обеих платформ. А внедрение общего набора API облегчает совместное использование кода во многих сценариях. Вы можете выбирать подходящие технологии для своих приложений: C#, Visual Basic, C++ или их сочетание на обеих платформах. Ресурсы на aka.ms/sharecode содержат много информации о создании приложений, способных работать как в Windows Phone 8, так и в Windows 8, и демонстрируют методики написания универсального кода для его максимального повторного использования в этих ОС.
Специфические области сравнения
Чтобы эффективно писать код для обеих платформ, вам нужно понимать различия в основной функциональности, а также знать средства, которые на высоком уровне кажутся сходными, но имеют разные API и реализации. Для такой функциональности даже не пытайтесь добиваться повторного использования кода. Я рассмотрю три основные области:
- UI и принципы работы;
- модель данных и соответствующий код;
- средства, специфичные для конкретных платформ.
UI и принципы работы
Форм-факторы устройств — главное, что нужно принимать во внимание при проектировании UI для кросс-платформенного приложения. Вы должны продумать такие аспекты, как разрешения экранов, их размеры и ориентацию устройство по умолчанию. Тщательно продумывайте решения при создании UI, чтобы оптимизировать удобство работы пользователей с учетом ограничений конкретного устройства.
Вы быстро осознаете, что нет смысла включать все средства приложения Windows Store в приложение Windows Phone 8 и что вы должны проектировать родной UI для каждой платформы. В табл. 1 показаны примеры таких различий в UI, которые надо учитывать для формирования наиболее дружественной к пользователю среды.
Табл. 1. Сравнение особенностей UI в Windows Phone 8 и Windows 8
Windows Phone 8 | Windows 8 |
Чаще всего касание пальцами одной руки | Касание пальцами одной или обеих рук, мышь |
Гарантированное аппаратное обеспечение, например камера и акселерометр | Никаких гарантий по наличию какого-либо специфического аппаратного обеспечения, требуется проверка в период выполнения |
Контент в несколько колонок нежелателен | Контент в табличном виде может отображаться без проблем |
Вертикальная прокрутка дополнительного контента; ограниченное место в панели приложения | Горизонтальная прокрутка дополнительного контента; много места в панели приложения |
Аппаратная кнопка возврата (Back) | Экранная кнопка возврата |
Нет поддержки контекстного масштабирования | Контекстное масштабирование (semantic zoom) |
Пространства имен XAML Хотя XAML для проектирования UI используется и в Windows 8, и в Windows Phone 8, не полагайтесь на повторное использование XAML между вашими приложениями. Платформы сильно отличаются по разметке страниц и ориентации, пространствам имен XAML и XAML-элементам управления, что делает повторное использование XAML крайне проблематичным.
Хотя многие элементы управления существуют для обеих платформ, они находятся в разных пространствах имен. Так, эквиваленты элементов управления Windows 8 в Windows Phone можно найти в Windows.UIXaml.Controls, а также в Microsoft.Phone.Controls и Microsoft.Phone.Shell, но System.Windows.Controls содержит элементы управления Windows 8 и некоторые общие элементы управления. К счастью, редактор XAML оповестит вас о попытке добавить неподдерживаемый элемент управления. Однако XAML не поддерживает условную компиляцию, поэтому простого способа включить пространства имен для той или иной платформы в период выполнения нет.
XAML-элементы управления Каждая библиотека элементов управления оптимизирована для соответствующей платформы. Поэтому настоятельно рекомендуется проектировать пользовательские элементы управления отдельно для каждой платформы. Это поможет сохранить согласованный UI на каждой платформе, в то же время уменьшив вероятность ошибок при портировании XAML. В табл. 2 показаны некоторые базовые элементы управления.
Табл. 2. Базовые элементы управления Windows Phone 8 и Windows 8
Windows Phone 8 | Windows 8 |
Корневым элементом управления в странице является PhoneApplicationPage | Корневым элементом управления в странице является Page |
Для вывода вертикально прокручиваемого контента используйте LongListSelector | Для вывода вертикально прокручиваемого контента используйте GridView |
Для пролистывания контента по горизонтали используйте Pivot | Для распределения множества элементов по сгруппированным сегментам используйте SemanticZoom (можно также применять элемент управления Grouped Items Page) |
Используйте ApplicationBar | Используйте AppBar |
Шаблоны Visual Studio для проектов Windows 8 создают LayoutAwarePage — подкласс Page в родном API, который предоставляет следующие дополнительные средства и гарантирует согласованность дизайна и UI:
- сопоставление состояния представления (view state) приложения с его визуальным состоянием;
- обработчики событий GoBack, GoForward и GoHome;
- сокращения с помощью мыши и комбинаций клавиш на клавиатуре при навигации;
- управление состоянием при навигации и управление жизненным циклом;
- модель представления по умолчанию.
Модель данных и соответствующий код
Все приложения должны управлять данными, и модели данных — лучший способ для этого. Они помогают улучшить сопровождение кода, добиться более высокой модульности, организации проекта и портируемости; кроме того, API, которые поддерживают все это, являются хорошими кандидатами для повторного использования кода. Тем не менее, не следует жертвовать архитектурой приложения или возможностями его сопровождения ради повторного использования кода. Общие библиотеки, методики написания универсального кода (code-sharing techniques) и такие шаблоны, как Model-View-ViewModel (MVVM), подойдут для этого гораздо лучше. Подробнее на эту тему см. статью Дуга Холланда (Doug Holland) «Code-Sharing Strategies for Windows Store and Windows Phone Apps» в июньском номере «MSDN Magazine» (msdn.microsoft.com/magazine/dn201744).
Средства, специфичные для конкретных платформ
Есть много средств, которые ведут себя похоже как в Windows 8, так и в Windows Phone 8, но реализуются по-разному. Из-за этого вы должны избегать повторного использования кода между платформами для определенных процессов и средств, включая:
- управление жизненным циклом приложения;
- системные задачи и контракты;
- плитки;
- всплывающие уведомления (toast notifications);
- локальное хранилище;
- работу с сетями;
- фоновую обработку;
- камеру;
- панель приложения.
Управление жизненным циклом приложения Хотя в жизненных циклах приложения в Windows Phone 8 и Windows 8 много общего, эти платформы имеют разные API. Как видно на рис. 1, высокоуровневые состояния программы и переходы между ними очень похожи на обеих платформах, но ресурсы в Windows Phone 8 гораздо более ограниченные, что и является причиной большинства расхождений в жизненном цикле. На обеих платформах только активное приложение может потреблять процессорные ресурсы (кроме фоновых задач, управляемых ОС).
Рис. 1. Жизненные циклы в Windows Phone 8 и Windows 8
Windows Phone 8 | Windows Phone 8 |
Closing | Закрывается |
Not Running | Не выполняется |
Launching | Запускается |
Deactivating | Деактивируется |
Running | Выполняется |
Dormant | Бездействует |
Activating | Активируется |
Tombstoned | Заморожено |
Windows 8 | Windows 8 |
Suspending | Приостанавливается |
Suspended | Приостановлено |
Resuming | Возобновляется |
Terminating | Завершается |
В табл. 3 показаны отличия в поведении в рамках жизненных циклов на двух платформах.
Табл. 3. Отличия жизненных циклов в Windows Phone 8 и Windows 8
Windows Phone 8 | Windows 8 |
Приложения Windows Phone 8 всегда запускаются или перезапускаются | Приложения Windows Store возобновляют работу без перехода на страницу |
Windows Phone 8 может замораживать (tombstone) приложения | Windows 8 либо приостанавливает, либо полностью завершает приложения. Приложения Windows Store могут поддерживать активацию размещенного представления (hosted-view activation), при которой приложение выполняет единственную задачу в рамках системного UI |
Windows Phone 8 поддерживает механизм Fast Application Resume (быстрое возобновление работы приложения) | В Windows 8 нет нужды в механизме Fast Application Resume, потому что приложения сохраняются в приостановленном состоянии так долго, насколько это возможно; в ином случае они завершаются |
В табл. 4 перечислены пространства имен, где содержатся события, связанные с жизненным циклом приложений.
Табл. 4. Пространства имен, относящиеся к жизненному циклу приложений
Windows Phone 8 | Windows 8 |
Производное от System.Windows.Application | Производное от Windows.UI.Xaml.Application |
Application_Launching | |
Application_Activated | OnLaunched |
Application_Deactivated | OnSuspending |
Application_Closing | |
На каждой платформе существует несколько точек входа в приложение, как показано в табл. 5.
Табл. 5. Точки входа в приложения
Windows Phone 8 | Windows 8 | Обе платформы |
Кнопка Speech | Кнопка Search | Плитка приложения |
App Connect | Кнопка Share | Дополнительные плитки |
| | Всплывающие оповещения |
| | Сопоставления протоколов и файлов |
Системные задачи и контракты В Windows 8 и Windows Phone 8 встроена поддержка распространенных операций, требующих координации с ОС. Windows 8 обрабатывает такие операции, используя контракты, тогда как Windows Phone 8 применяет задачи (например, Launchers и Choosers). Контракты и задачи дают сходные возможности пользователю, но разработка с их применением различается. Они не обязательно предоставляют функциональность «один в один», поэтому вы должны внимательно анализировать задачи и контракты при портировании приложения.
API задач Windows Phone 8 находятся в пространстве имен Microsoft.Phone.Tasks: PhotoChooserTask, EmailAddressChooseTask, SaveContractTask и др. В противоположность этому контракты Windows 8 имеют индивидуальные API, относящиеся к панелям, которые открываются с помощью чудо-кнопок (панели поиска, обмена информацией и прочее); поддержка контрактов объявляется в манифесте приложения. Контракты — это, по сути, соглашения, и их реализация включает переопределение методов в классе Application или обработку событий от классов в Windows API.
Плитки Плитки являются точками входа в приложения Windows Store и Windows Phone 8. Основные плитки просто запускают приложения, тогда как дополнительные плитки могут быть закреплены на экране Start; в конечном счете они представляют собой так называемые глубокие ссылки («deep links»), которые перемещают пользователя на конкретную страницу в приложении. Обе платформы поддерживают активные плитки, контент которых периодически обновляется, но их API совершенно разные. В табл. 6 описываются плитки в Windows Phone 8 и Windows 8.
Табл. 6. Сравнение плиток в Windows Phone 8 и Windows 8
Плитки в Windows Phone 8 | Плитки в Windows 8 |
Три размера: малый, средний и широкий | Два размера: мельче и крупнее |
Стандартные плитки, переворачивающиеся плитки (flip tiles), циклические плитки (cyclic tiles) и плитки со значками (iconic tiles) (Microsoft.Phone.Shell) | SecondaryTile можно настраивать с помощью XML-шаблонов (Windows.UI.StartScreen) |
Изображения плиток предоставляются в манифесте | Изображения плиток предоставляются в манифесте |
Дополнительные плитки создаются статическим методом ShellTile.Create | Дополнительные плитки создаются методом SecondaryTile.RequestCreateAsync |
Плитки приложения обновляются с помощью ShellTile.Update (Microsoft.Phone.Shell); уведомления отправляются с использованием ShellTileSchedule (ShellTileToast также обновляет плитки) | Плитки приложения обновляются с помощью TileUpdateManager и TileNotification (Windows.UI.Notifications) |
Пользователь может открепить плитку приложения | Пользователь может отключить активную плитку |
На рис. 2 и 3 можно сравнить код для создания дополнительной плитки. В Windows Phone 8 класс ShellTile предоставляет статический интерфейс для создания (и удаления) дополнительной плитки. Вы можете использовать один из нескольких классов, которые инкапсулируют данные плитки: StandardTile, CycleTileData, FlipTileData или IconicTileData. В Windows 8 есть лишь одна структура данных для определения дополнительной плитки (SecondaryTile). Создание плитки осуществляется асинхронным запросом, который предлагает пользователю закрепить плитку на экране Start или отказаться от этого.
Рис. 2. Создание плитки в Windows Phone 8
CycleTileData tileData = new CycleTileData()
{
Title = item.Title,
SmallBackgroundImage = new Uri(item.GetImageUri(),
UriKind.RelativeOrAbsolute),
CycleImages = list
};
ShellTile.Create(new Uri(navDataSource,
UriKind.Relative), tileData, true);
Рис. 3. Создание плитки в Windows 8
var tile = new SecondaryTile(
item.UniqueId, // ID плитки
item.ShortTitle, // краткое имя плитки
item.Title, // отображаемое имя плитки
item.UniqueId, // аргумент активации
TileOptions.ShowNameOnLogo, // параметры плитки
uri // URI эмблемы плитки
);
await tile.RequestCreateAsync();
Всплывающие уведомления Всплывающие уведомления (toast notifications) Windows 8 аналогичны напоминаниям и оповещениям в Windows Phone 8. Они позволяют приложению уведомлять пользователя о каком-то событии в данное время. Щелкнув всплывающее уведомление, вы запускаете приложение, если оно закрыто, или возобновляете его работу, если оно приостановлено.
Windows Phone 8 поддерживает два типа уведомлений: оповещение (alarm) и напоминание (reminder). Кроме того, оно может отображать всплывающие уведомления (даже из фоновой задачи) с помощью ShellToast. Оповещения и напоминания находятся в Microsoft.Phone.Scheduler, а ShellToast — в Microsoft.Phone.Shell.
Windows 8 использует всплывающие уведомления через ToastNotificationManager и ScheduledToastNotification, которые находятся в пространстве имен Windows.UI.Notifications и включаются через манифест приложения.
Локальное хранилище Пространство имен Windows.Storage предоставляет новый набор общих API, которые позволяют приложениям управлять локальными файлами. В Windows Phone 8 System.IO.IsolatedStorage.IsolatedStorageFile обеспечивает обратную совместимость с более ранними версиями Windows Phone, но вы должны использовать новые API. Для сохранения данных приложения в локальном хранилище можно использовать сериализацию и Windows.Storage.ApplicationData.Current.LocalFolder.
Обе платформы поддерживают хранение пар «ключ-значение» (параметры), а также файлов и папок. Однако Windows Phone 8 API являются подмножеством полных API и не поддерживают хранение перемещаемых данных (roaming data), временных данных, локальных или перемещаемых настроек. В табл. 7 дана сводка параметров хранилища для каждой платформы.
Табл. 7. Параметры хранилища в Windows Phone 8 и Windows 8
Функционал и пространство имен | Описание | Windows Phone 8 | Windows 8 |
Windows.Storage | Локальное файловое хранилище приложения | Да | Да |
System.IO.IsolatedStorage.IsolatedStorageFile | Локальное файловое хранилище приложения | Да | Нет |
Настройки ApplicationData (LocalFolder) | Хранилище пар «ключ-значение» | Нет | Да |
System.IO.IsolatedStorage.IsolatedStorageSettings | Хранилище пар «ключ-значение» | Да | Нет |
SQL CE | База данных | Да | Нет |
Работа с сетями Корректная работа большинства приложений сильно зависит от возможностей их устройств в подключении к Интернету. Как в Windows 8, так и в Windows Phone 8 необходимые возможности заявляются в манифесте. В табл. 8 перечислены релевантные сетевые API.
Табл. 8. Отличия в сетевых API в Windows Phone 8 и Windows 8
Windows Phone 8 | Windows 8 | Обе платформы |
ConnectionManager | NetworkInterface - System.Net.NetworkInformation
| HttpWebRequest, HttpWebResponse |
DatagramSocket, StreamSocket - Windows.Networking.Sockets
| Socket (TCP или UDP), StreamSocket | |
HttpClient | WebClient | |
В Windows 8 введен HttpClient, которые действует как сеанс, отправляющий запросы HTTP-серверу (GET, POST и PUT). У каждого экземпляра HttpClient свой пул соединений. Данные возвращаются в виде строки, HttpRequestMessage, потока или байтового массива.
С другой стороны, в Windows 8 нет WebClient (кроме настольных приложений). Он используется в приложениях Windows Phone 8, и его реализация немного отличается от реализации WebClient в более ранних версиях Windows. В Windows Phone 8 вы также можете использовать HttpWebRequest/HttpWebResponse с асинхронной оболочкой. Предварительная версия портируемого HttpClient теперь доступна для обеих платформ. Вы можете получить ее из NuGet Gallery.
Фоновая обработка В некоторых ситуациях вам может понадобиться выполнение кода в фоне: потоковая передача музыки, запрос сервера на наличие обновлений, скачивание файла и т. д. На обеих платформах вы можете передать ОС выполнение какой-либо задачи при срабатывании того или иного триггера. Эти задачи независимы от приложения, и ОС имеет полный контроль над ними.
Для каждого приложения может быть только один фоновый агент, но этот агент может выполнять одну или обе из следующих задач:
- периодические задачи — короткие задачи, которые ОС может выполнять через каждые 30 минут;
- задачи, интенсивно использующие ресурсы, — более длительные задачи, выполняемые, когда смартфон подключен к электросети или имеет емкие аккумуляторы.
В табл. 9 показано, что нужно для реализации фоновых задач на обеих платформах. Заметьте, что приложения Windows Store, использующие фоновые задачи, должны объявлять об этом в своем манифесте.
Табл. 9. Использование фоновых задач в Windows Phone 8 и Windows 8
Windows Phone 8 | Windows 8 |
Наследуется от BackgroundAgent или одного из его подклассов: - пространства имен Microsoft.Phone и Microsoft.Phone.Scheduler
| Windows.ApplicationModel.Background |
Переопределение метода OnInvoke и вызов NotifyComplete по окончании | Реализация интерфейса IBackgroundTask и его метода Run |
Проверка на то, что задача еще не зарегистрирована | Фоновые задачи объявляются в манифесте; проверка на то, что задача еще не зарегистрирована |
Добавление и удаление фоновых агентов через ScheduledActionService | Создание и регистрация экземпляра вашей задачи через BackgroundTaskBuilder |
| Обработка события BackgroundTaskCompleted для получения данных от задачи |
Теперь я продемонстрирую, как реализовать фоновую задачу — сначала в Windows 8, а затем в Windows Phone 8.
Ниже перечислены высокоуровневые операции для Windows 8.
- Реализуйте интерфейс IBackgroundTask и метод Run.
- Объявите об использовании фоновой задачи в манифесте.
- Проверьте, что задача еще не зарегистрирована.
- С помощью BackgroundTaskBuilder создайте и зарегистрируйте экземпляр задачи.
- Обработайте событие BackgroundTaskCompleted, чтобы получить данные от задачи:
using Windows.ApplicationModel.Background;
namespace MyTaskExample
{
public class SimpleBackgroundTask : IBackgroundTask
{
public void Run(IBackGroundTaskInstance task)
{
// Здесь выполняем работу...
}
}
}
- Объявите, что приложение использует фоновую задачу:
<Extensions>
<Extension Category="windows.backgroundTasks"
EntryPoint="Tasks.MyTask">
<BackgroundTasks>
<Task Type="systemEvent" />
</BackgroundTasks>
</Extension>
</Extensions>
- И проверьте регистрацию:
foreach (var task in Background.BackgroundTaskRegistration.AllTasks)
{
// Используйте if (task.Value.Name == taskName),
// чтобы узнать, не зарегистрирована ли уже задача
}
// Если не зарегистрирована...
var taskBuilder = new BackgroundTaskBuilder();
taskBuilder.Name = taskName;
taskBuilder.TaskEntryPoint = "Tasks.MyTask";
taskBuilder.SetTrigger(new SystemTrigger(
SystemTriggerType.TimeZoneChange, false));
BackgroundTaskRegistration myTaskRegistration =
taskBuilder.Register();
Далее перечислены высокоуровневые операции для Windows Phone 8:
- Создайте ScheduledTaskAgent (шаблон Windows Phone Scheduled Task Agent):
public class ScheduledAgent : ScheduledTaskAgent
{
protected override void OnInvoke(ScheduledTask task)
{
// Здесь напишите код для выполнения задачи...
NotifyComplete();
}
}
- Проверьте, что задача уже запланирована для выполнения, и, если это не так, создайте новую; в ином случае удалите существующую задачу (задача планируется на периодическое выполнение в течение десяти дней):
PeriodicTask task = ScheduledActionService.Find(
taskName) as PeriodicTask;
bool found = (task != null);
if (!found)
task = new PeriodicTask(taskName);
else
ScheduledActionService.Remove(taskName);
task.Description = description;
task.ExpirationTime = DateTime.Now.AddDays(10);
ScheduledActionService.Add(task);
В отличие от Windows 8 здесь нет нужды объявлять о поддержке фоновых задач в манифесте.
Камера Windows Phone 8 и Windows 8 поддерживают захват изображений и видео, но, как и в случае других функций, их API отличаются.
Захват фотоснимков в Windows Phone 8 обрабатывается ОС. Вы можете зарегистрировать обратный вызов для обработки результата, когда пользователь выходит из UI камеры. В качестве результата вы можете и не получить фотоснимок, поэтому перед использованием результата обязательно проверяйте его. Видеозапись не встроена в задачу захвата камеры, поэтому она потребует больше работы.
Windows Phone 8 обладает уникальной возможностью, позволяющей создавать фотоприложения для камеры (lens apps). Вы также можете создавать весьма функциональные фотоприложения для просмотра или редактирования фотоснимков. Более того, камеру можно использовать как шлюз к другим возможностям. Например, приложения для чтения штрих-кодов используют камеру для сканирования штрих-кода, а затем отображают связанные с ним данные. Все эти приложения поддерживают различные расширения. С помощью специальных API можно программным способом обращаться даже к датчику с видеокамерой (camera sensor). Более подробные сведения по этой тематике см. в «Lens extensibility for Windows Phone 8» (aka.ms/Vdgk8e) и «Capturing photos for Windows Phone» (aka.ms/Owcwpl) в Windows Phone Dev Center.
В Windows 8 для фотоснимков и видео применяется CameraCaptureUI (Windows.Media.Capture). Для этого в манифесте нужно разрешить использование Webcam и Microphone:
private async void OnCapturePhoto(object sender,
TappedRoutedEventArgs e)
{
var camera = new CameraCaptureUI();
var file = await camera.CaptureFileAsync(
CameraCaptureUIMode.Photo);
if (file != null)
{
// Здесь что-то делаем с результатом...
}
}
Windows Phone 8 делает снимки с помощью CameraCaptureTask (Microsoft.Phone.Tasks). Это требует включения ID_CAP_ISV_CAMERA и ID_CAP_MICROPHONE в манифест, как показано на рис. 4.
Рис. 4. Включение ID_CAP_ISV_CAMERA и ID_CAP_MICROPHONE в манифест в Windows Phone 8
private readonly CameraCaptureTask cameraTask;
public Init() {
cameraTask = new CameraCaptureTask();
cameraTask.Completed += PhotoCaptured;
}
public void TakePhoto() {
cameraTask.Show();
}
private async void PhotoCaptured (object sender,
PhotoResult result){
await Task.Run(() => {
// Здесь что-то делаем с результатом...
});
}
Панель приложения В Windows 8 панели приложений гораздо функциональнее, чем в Windows Phone 8. На панель приложения можно помещать кнопки для наиболее распространенных операций вроде добавления, редактирования и удаления каких-либо элементов. Приложение уведомляется об открытии или закрытии панели приложения через события Opened и Closed.
В том, как работает панель приложения на каждой платформе, есть существенные различия, показанные в табл. 10.
Табл. 10. Различия в работе панели приложения в Windows Phone 8 и Windows 8
Windows Phone 8 | Windows 8 |
Одна панель приложения внизу страницы | Две панели приложения: одна — внизу, а другая — наверху |
Допускается лишь четыре элемента - дополнительные элементы помещаются в меню
- группирование не поддерживается
| Ведет себя аналогично любому контейнеру - меню не поддерживаются
- можно группировать элементы во вложенные контейнеры
|
Элемент управления ApplicationBar в PhoneApplicationPage.ApplicationBar | Элемент управления AppBar в Page.BottomAppBar или Page.TopAppBar |
Установите Mode в Default для вывода панели приложения при загрузке страницы | Установите IsOpen в true для вывода панели приложения при загрузке страницы |
Установите IsMenuEnabled, чтобы разрешить использование меню | Установите IsSticky в true, чтобы панель приложения всегда оставалась открытой |
Объявление панели приложения в Windows 8 показано на рис. 5. Обратите внимание на то, что для группирования кнопок используются две панели стека (stack panels) с одной группой слева и другой группой справа.
Рис. 5. Объявление панели приложения в Windows 8
<Page.BottomAppBar IsOpen="True">
<AppBar x:Name="bottomAppBar" Opened="AppBar_Opened"
Padding="10,0,10,0">
<Grid>
<StackPanel Orientation="Horizontal"
HorizontalAlignment="Left">
<Button Style="{StaticResource TakePictureAppBarButtonStyle}"
Click="TakePicture_Click"/>
<Button Style="{StaticResource ShareTaskAppBarButtonStyle}"
Click="ShareImage_Click"/>
</StackPanel>
<StackPanel Orientation="Horizontal"
HorizontalAlignment="Right">
<Button Style="{StaticResource StartCoookingAppBarButtonStyle}"
Click="StartCooking_Click"/>
<Button Style="{StaticResource PinToStartAppBarButtonStyle}"
Click="PinToStart_Click"/>
</StackPanel>
</Grid>
</AppBar>
</Page.BottomAppBar>
На рис. 6 показано объявление панели приложения в Windows Phone 8 (заметьте, что в ApplicationBar допускаются лишь четыре элемента ApplicationBarIconButton, и никакие контейнеры в нем не поддерживаются).
Рис. 6. Объявление панели приложения в Windows Phone 8
<phone:PhoneApplicationPage.ApplicationBar x:name="ddd">
<shell:ApplicationBar x:Name="bottomAppBar" IsVisible="True"
IsMenuEnabled="True" Mode="Default" Opacity="1.0">
<shell:ApplicationBarIconButton x:Name="btnTakePicture"
IconUri="/Assets/Icons/camera.png"
Click="btnTakePicture_Click"
Text="Take Picture"/>
<shell:ApplicationBarIconButton x:Name="btnShareTask"
IconUri="/Assets/Icons/share.png"
Click="btnShareShareTask_Click"
Text="Share Image"/>
<shell:ApplicationBarIconButton x:Name="btnStartCooking"
IconUri="/Assets/Icons/alarm.png"
Click="btnStartCooking_Click"
Text="Start Cooking"/>
<shell:ApplicationBarIconButton x:Name="btnPinToStart"
IconUri="/Assets/Icons/like.png"
Click="btnPinToStart_Click"
Text="Pin To Start"/>
</shell:ApplicationBar>
</phone:PhoneApplicationPage.ApplicationBar>
Заключение
Потребители все чаще ожидают одинаковой UI-среды на своих смартфонах и других устройствах. Общее ядро Windows 8 и Windows Phone 8 обеспечивает приемлемый уровень повторного использования при создании решений для обеих платформ. Однако, как вы видели в этой статье, важно понимать основные отличия физических устройств и принципы взаимодействия пользователей с ними, а также различия в API для этого на двух платформах. Эти отличия означают, что проектировщики приложений должны озаботиться созданием раздельных UI и пользовательских сред, а это значит, что повторно использовать XAML между платформами практически не удастся. Хотя некоторые API доступны для обеих платформ, как в случае Windows.Store.StorageFile, многие средства очень схожи, но реализуются по-разному. Это относится к событиям жизненного цикла, плиткам, захвату медийных данных, задачам и контрактам, настройкам, фоновым задачам и панелям приложений.
Как только вы поймете эти различия, вы сможете уверенно применять методики кросс-платформенного повторного использования кода, например Portable Class Libraries, компоненты исполняющей среды и т. д. Чтобы узнать больше об этих методиках, пожалуйста, обратитесь к статье Дуга Холланда, о которой я уже упоминал, а также к материалам в Windows Phone Dev Center по ссылке aka.ms/sharecode. И советую скачать пример кода, показывающий совместное использование кода в действии, по ссылке aka.ms/gxcvq3.