Как вы уже знаете, благодаря Windows 10 вы можете:
- писать конкретные приложения для каждого семейства устройств (мобильных, настольных, Xbox, и т.д.).
- писать приложения, которые будут работать на всех из них.
в итоге можно быть уверенным ,что в конце концов придет момент, когда надо будет адаптировать:
- UX для работы с различными устройствами, имеющими различные механизмы ввода/вывода — например, клавиатуры, мыши, ручки, сенсор, игровые контроллеры, взгляд, жест, речь и т.д., а также для больших/ маленьких/нескольких экранов или их отсутствия и т.п..
- функционал, который работает с различными сборками Windows, построен на общем ядре используя различные «контракты» для работы со специфичным API.
по первому пункту все просто. Нам в помощь было добавлено несколько новых возможностей, что бы справиться с новыми заботами:
- новый контрол RelativePanel
- новые возможности Visual State Management, которые помогают автоматически реагировать на изменение размеров (AdaptiveTrigger) и моментальное изменение свойств (даже относительное позиционирование в RelativePanel)
Эта возможность поможет нам лучше реагировать на «размер экрана» и, возможно, это лучше, чем привязывать поведение непосредственно к семейству устройств (настольные мобильные и т.п.), т.к. становится все труднее узнать, какое железо может лежать в том или ином устройстве.
Все это кажется достаточно очевидным, если говорить о настольных компьютерах — мы привыкли к тому, что у настольного компьютера может быть 2 или 3 монитора с различными разрешениями и разной плотностью пикселей и т.п. В таком случае набор железа очень гибок и не является фиксированным.
Но если брать во внимание семейство «мобильных» — то все было логично, т.к. это всегда означало, что у устройства маленький экран, он один и имеет сенсорный ввод. Но все эти утверждения были верны лишь до выхода Windows 10 на рынок с ее возможностью Continuum, где, внезапно, такое устройство как телефоне может получить большой монитор и мышь.
Для того, что бы разобраться, как же все-таки разбивать ресурсы, если нам это понадобилось, было собрано небольшое демо и вот как оно выглядит на разных платформах:
это просто чистый проект, в котором DataContext задается из кода страницы:
using System; using System.Linq; using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; using Windows.UI.Xaml.Media; namespace App4 { public sealed partial class MainPage : Page { public MainPage() { this.InitializeComponent(); this.Loaded += OnLoaded; } private void OnLoaded(object sender, RoutedEventArgs e) { Random r = new Random(); this.DataContext = Enumerable.Range(1, 100).Select( i => new SolidColorBrush( Windows.UI.Color.FromArgb( 0xFF, (byte)r.Next(0, 255), (byte)r.Next(0, 255), (byte)r.Next(0, 255)))); } } }
Как вы видите это попросту список цветов, который цепляется к GridView для отображения на страничке:
<Page x:Class="App4.MainPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:App4" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"> <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"> <GridView ItemsSource="{Binding}" ItemTemplate="{StaticResource myTemplate}"> </GridView> </Grid> </Page>
а также подключенные ресурсы в файле App.xaml:
<Application x:Class="App4.App" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:App4" RequestedTheme="Light"> <Application.Resources> <ResourceDictionary> <ResourceDictionary.MergedDictionaries> <ResourceDictionary Source="Resources.xaml"/> </ResourceDictionary.MergedDictionaries> </ResourceDictionary> </Application.Resources> </Application>
Ну и конечно же 2 папки с 2-мя файлами ресурсов, которые выбираются автоматически в зависимости от устройства.
квадратный шаблон:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:App4.DeviceFamily_Desktop"> <DataTemplate x:Key="myTemplate"> <Rectangle Width="100" Height="100" Fill="{Binding}"/> </DataTemplate> </ResourceDictionary>
и круглый шаблон:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:App4.DeviceFamily_Mobile"> <DataTemplate x:Key="myTemplate"> <Ellipse Width="100" Height="100" Fill="{Binding}"/> </DataTemplate> </ResourceDictionary>
Впринципе это небольшой нюанс, но он может помочь вам при планировании и построении структуры проекта. Так же вы могли сделать одну страничку и один файл ресурсов и менять шаблон с помощью триггеров, в зависимости от размеров страницы (в развернутом состоянии был бы квадратный шаблон, а в маленьком (сжатом) — круглый). Все зависит от поставленной задачи.
Так же вы можете определить отдельный шаблон для мобильных устройств, не создавая отдельного файла ресурсов, а просто прописть свой триггер в визуальных состояниях:
<Page x:Class="App4.MainPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:App4" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"> <Page.Resources> <DataTemplate x:Key="square"> <Ellipse Width="100" Height="100" Fill="{Binding}"/> </DataTemplate> <DataTemplate x:Key="round"> <Rectangle Width="100" Height="100" Fill="{Binding}"/> </DataTemplate> </Page.Resources> <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"> <VisualStateManager.VisualStateGroups> <VisualStateGroup x:Name="stateGroups"> <VisualState x:Name="Default"/> <VisualState x:Name="Mobile"> <VisualState.StateTriggers> <local:DeviceFamilyTrigger DeviceFamily="Windows.Mobile"/> </VisualState.StateTriggers> <VisualState.Setters> <Setter Target="gridview.ItemTemplate" Value="{StaticResource round}"/> </VisualState.Setters> </VisualState> </VisualStateGroup> </VisualStateManager.VisualStateGroups> <GridView x:Name="gridview" ItemsSource="{Binding}" ItemTemplate="{StaticResource square}"> </GridView> </Grid> </Page>
namespace App4 { using Windows.System.Profile; using Windows.UI.Xaml; class DeviceFamilyTrigger : StateTriggerBase { public DeviceFamilyTrigger() { base.SetActive(AnalyticsInfo.VersionInfo.DeviceFamily == this.DeviceFamily); } public string DeviceFamily { get; set; } } }
Как вы видите, в Windows 10 у нас появилась дополнительная работа — все состояния (для различных размеров настольного приложения + мобильное отображение и т.п) необходимо\можно реализовывать в одном файле в одном приложении, но Microsoft предоставил нам достаточное количество способов решения данной задачи: разбитие файлов ресурсов или страничек по папкам (папка будет выбираться в зависимости от устройства, на котором запустилось приложение), реализовать различный интерфейс в зависимости от размеров экрана, использовать триггеры в визуальных состояниях.
Ссылка на источник: Windows 10, UWP and DeviceFamily-Specific Resource Dictionaries
Добавить комментарий