Для начала, хотелось бы напомнить, каким образом можно было создавать универсальные приложения в Windows 8.1. Создавалось решение с тремя проектами: для телефона, для Windows 8.1 и проект с общим кодом. А как теперь в Windows 10? Сейчас расскажу.

Вот так выглядело универсальное приложение в Windows 8.1



Но потом появилась Windows 10 и сразу возник резонный вопрос:
Это что ж теперь учить все заново?


Отчасти небольшие изменения действительно есть. Но если у вас было хорошее понимание универсальных проектов Windows 8.1, то для вас все будет привычно. Более того добавилась определенная гибкость.

Давайте сначала рассмотрим какие устройства на платформе Windows UWP существуют на данный момент (в продаже, в планах или в прототипе):



Устройства объединены в отдельные семейства:



На диаграмме стоит многоточие, так как платформа растет и видов устройств может стать больше со временем.

Теперь вместо того, чтобы получить решение с несколькими проектами под каждое семейство устройств достаточно создать папку, указав в ее названии имя семейства. Например, так:


В данном случае, если приложение будет запущено на мобильном устройстве, то будет отображена страница MainPage из папки DeviceFamily-Mobile.
Причем, заметьте, если вы создадите страницу внутри папки с названием MainPage, то она будет создана без файла кода MainPage.xaml.cs

Это был первый способ.

Второй способ аналогичен первому, но вместо создания папки к имени файла добавляется .DeviceFamily-Type



Третий способ – из codebehind.
Если скомпилировать проект и рассмотреть файл MainPage.g.i.cs то можно найти перегрузку метода InitializeComponent, которая принимает в качестве параметра System.Uri resourceLocator

public void InitializeComponent(global::System.Uri resourceLocator)
        {
            if (_contentLoaded)
                return;

            _contentLoaded = true;

            if (resourceLocator == null)
            {
                resourceLocator = new global::System.Uri("ms-appx:///MainPage.xaml");
            }
            global::Windows.UI.Xaml.Application.LoadComponent(this, resourceLocator, global::Windows.UI.Xaml.Controls.Primitives.ComponentResourceLocation.Application);
        }

А значит для того чтобы загрузить нужную страницу мы можем поступить так:

public MainPage()
{            
if (Windows.System.Profile.AnalyticsInfo.VersionInfo.DeviceFamily=="Windows.Mobile")
            {
              InitializeComponent(new Uri("ms-appx:///MobileMainPage.xaml", UriKind.Absolute));   
            }
            else
            {
                InitializeComponent();
            }
}

В данном случае если приложение будет запущено на мобильном устройстве, то будет загружена страница MobileMainPage.xaml

Теперь немного о том как в коде C# определить какое семейство устройств используется на данный момент. Сделать это очень просто с помощью такого вот кода:

  if (String.Equals(Windows.System.Profile.AnalyticsInfo.VersionInfo.DeviceFamily, "Windows.Desktop"))
            {
// значит семейство Desktop и можно что-то нужное сделать
               }

Если вы захотите использовать в своем приложении API определенного семейства устройств, то вы можете добавить ссылку на любое из расширений платформы UWP



Избитым примером использования API семейства устройств можно считать проверку на присутствие аппаратной кнопки «Назад» на телефоне (hardware Back button).

            bool isHardwareButtonsAPIPresent =
Windows.Foundation.Metadata.ApiInformation.IsTypePresent("Windows.Phone.UI.Input.HardwareButtons");

            if (isHardwareButtonsAPIPresent)
            {
                Windows.Phone.UI.Input.HardwareButtons.CameraPressed += HardwareButtons_CameraPressed;
            }
        private void HardwareButtons_CameraPressed(object sender, Windows.Phone.UI.Input.CameraEventArgs e)
        {
            // здесь своя реализация события нажатия «Назад»
        }

Для проверки используется метод isTypePresent который содержится в классе Windows.Foundation.Metadata.ApiInformation. Этот класс обладает также и другими методами для проверки на наличие доступных возможностей API (событий, свойств…)

Или вот чуть менее избитый пример, который в случае наличия у устройства статусбара меняет его цвет на шоколадный:

            if (Windows.Foundation.Metadata.ApiInformation.IsTypePresent("Windows.UI.ViewManagement.StatusBar"))
            {
                var statusBar = Windows.UI.ViewManagement.StatusBar.GetForCurrentView();
                statusBar.BackgroundColor = Windows.UI.Colors.Chocolate;
                statusBar.BackgroundOpacity = 1;
            }




Пример можно найти на GitHub

Комментарии (5)


  1. Dima_Sharihin
    14.10.2015 09:00

    Интересно, почему Raspberry Pi отнесли к Headless SKU?


    1. asommer
      14.10.2015 09:08
      +1

      Headless означает что можно работать без монитора и клавиатуры (или даже без кабелей совсем)


    1. HomoLuden
      14.10.2015 16:35

      Потому, что, видимо, пока есть только headless-сборка для него. Если изобретут «иксы» виндовые, на поддержку которых хватит ресурсов RPi, то появится и «headness»-сборка.


      1. asommer
        14.10.2015 19:13

        Системные требования у 10-ки довольно скромные:
        1 GHz or faster processor or SoC
        1 GB for 32-bit OS 2 GB for 64-bit OS

        а у Windows 10 IoT Core совсем скромные:
        400 MHz or faster x86, x64 processor or ARM SoC
        256 MB available to the OS for devices without display support
        512 MB available to the OS for devices with display support, depending on resolution

        Так что у Raspberry Pi 2 в 2 раза больше ресурсов, чем требуется для винды
        Minimum hardware requirements


        1. HomoLuden
          16.10.2015 16:27

          В таком случае просто не реализована еще сборка с граф. интерфейсом. Возможно, позже появится семейство с графикой для RPi 2 в описанном подходе.