Pull to refresh

3 способа задать разметку для различных устройств в C#/XAML приложениях Windows UWP

Reading time3 min
Views15K

Для начала, хотелось бы напомнить, каким образом можно было создавать универсальные приложения в 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
Tags:
Hubs:
Total votes 15: ↑14 and ↓1+13
Comments5

Articles