Использование адаптивных XAML-представлений и визуальных состояний позволяет создавать адаптивную разметку xaml, которая будет меняться в зависимости от типа устройства или ширины экрана. Но также может возникнуть задача сделать адаптивным и код c#: например, добавить в приложение на мобильных платформах какие-то отдельные функции, которые не нужны на десктопах. Так, к примеру, на мобильных устройствах есть кнопка "Назад", и, возможно, мы ей захотим воспользоваться программно. А десктопах естественно нам эта функция не нужна.
Чтобы сделать код C# адаптивным, нам надо выполнить пару шагов. Вначале нам надо добавить в в проект соответствующие расширения SDK. Допустим, мы хотим добавить код, который бы обрабатывал нажатие на кнопку "Назад" на мобильных устройствах. Для этого нажмем в проекте правой кнопкой на узел References и в выпадающем меню выберем пункт Add Reference. После этого нам открывается окно добавления библиотеки в проект. В этом окне слева выберем Universal Windows - > Extensions, а в центральном поле выберем пункт Windows Mobile Extensions for the UWP:
Эти расширения позволяют нам добавить в приложение тот функционал, который отсутствует в универсальной платформе, но который может применяться на конкретных устройствах - десктопах, смартфонах или IoT.
Если есть несколько версий одного и того же расширения, то лучше взять более новую версию.
Второй этап заключается в использовании класса Windows.Foundation.Metadata.ApiInformation. Этот класс позволяет проверить наличие на текущем устройстве определенных функциональностей. Для этого в нем определены следующие методы:
IsApiContractPresent
: возвращает true, если устройство поддерживает определенный API
IsEnumNamedValuePresent
: возвращает true, если устройство поддерживает определенную константу из определенного перечисления
IsEventPresent
: возвращает true, если устройство поддерживает определенное событие для определенного типа
IsMethodPresent
: возвращает true, если устройство поддерживает определенный метод для определенного типа
IsPropertyPresent
: возвращает true, если устройство поддерживает определенное свойство для определенного типа
IsReadOnlyPropertyPresent
: возвращает true, если устройство поддерживает определенное свойство только для чтения для определенного типа
IsWriteablePropertyPresent
: возвращает true, если устройство поддерживает определенное свойство только для записи для определенного типа
IsTypePresent
: возвращает true, если устройство поддерживает определенный тип
Так, наша задача состоит в обработке кнопки Назад на мобильных устройствах. Кнопка Назад представлена классом Windows.Phone.UI.Input.HardwareButtons. Поэтому изменим код MainPage.xaml.cs следующим образом:
using Windows.Foundation.Metadata; using Windows.Phone.UI.Input; using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; namespace ApiExtensionsApp { public sealed partial class MainPage : Page { public MainPage() { this.InitializeComponent(); if (ApiInformation.IsTypePresent("Windows.Phone.UI.Input.HardwareButtons")) HardwareButtons.BackPressed += HardwareButtons_BackPressed; } private void HardwareButtons_BackPressed(object sender, BackPressedEventArgs e) { if (Frame.CanGoBack) Frame.GoBack(); else Application.Current.Exit(); // выход из приложения } } }
Условное выражение
if (ApiInformation.IsTypePresent("Windows.Phone.UI.Input.HardwareButtons"))
позволяет проверить на запускаемом устройстве наличие кнопки Назад. Если она есть, то прикрепляем обработчик этой кнопки.
Если бы мы не использовали проверку на наличие типа и просто устанавливали бы обработчик события, то при запуске на десктопе приложение вываливалось бы в ошибку. Поэтому вещи, которые являются специфичными для определенной платформы, необходимо проверять перед использованием.
Аналогично мы бы могли использовать для проверки наличия функционала и другие методы класса ApiInformation. Например, проверка на событие:
if (ApiInformation.IsEventPresent(typeof(HardwareButtons).FullName, "BackPressed"))
Проверка на контракт API:
if (ApiInformation.IsApiContractPresent("Windows.Phone.PhoneContract", 1))
В данном случае проверяется наличие контракта Windows.Phone.PhoneContract
, который применяется на мобильных устройствах, причем проверяется именно 1-я версия.
Собственно на данный момент это актуальная версия. Более точно версию API можно посмотреть в окне Object Browser.