- PVSM.RU - https://www.pvsm.ru -

Fall Creators Update: важное для программиста

Классические дотнетовские приложения хороши тем, что они практически не ограничены в правах и, например, могут работать в трее. Зато универсальные приложения (UWP) более безопасны, и их можно устанавливать и удалять бесчисленное количество раз, не забивая систему и реестр мусором. Платформа UWP постоянно развивается, и, пока пользователи обновляются до Fall Creators Update, который вышел в октябре этого года, мы, разработчики, можем посмотреть на его новые и интересные возможности.

Fall Creators Update: важное для программиста - 1

Готов? Скачивай последнюю SDK с официальной страницы [1], и начнем нашу ознакомительную экскурсию.

Примечание: мы продолжаем серию публикаций полных версий статей из журнала Хакер. Орфография и пунктуация автора сохранены.

В первую очередь хотелось бы заметить про множественные улучшения в дизайнере XAML. Одним из самых ожидаемых улучшений для меня является повышение скорости работы. Сравните скорость загрузки в Fall Creators Update (слева) с простым Creators Update:

Fall Creators Update: важное для программиста - 2

На конференции Build 2017 Microsoft анонсировала новую систему UI дизайна под названием Fluent [2].

Fall Creators Update: важное для программиста - 3

И вот начиная с этого обновления в UWP начнут появляться новые элементы управления, основанные на этой системе.

Navigation View

Это out of box контрол для отображения меню.

Fall Creators Update: важное для программиста - 4

Меню выпадает с левой стороны. Кроме того, к меню относится и полоска сверху — Header. На эту полоску можно вынести какой-то текст заголовка или какие-то дополнительные кнопки.
Меню может использоваться в 3-ех различных вариациях. Вариант отображенный сверху это Minimal. В этом режиме Header скрыть нельзя, так как на нем находится кнопка «гамбургер». Есть еще режим Compact в котором справа отображаются иконки меню.

Fall Creators Update: важное для программиста - 5

В режиме Expanded меню отображается раскрытым.

Изменяя размер окна вашего приложения вы можете изменить режим Navigation View. Ведь система автоматически выбирает режим исходя из размера окна приложения. На этот выбор можно повлиять, указав различные значения пикселей атрибутам OpenPaneLength, CompactModeThresholdWidth и ExpandedModeThresholdWidth.

Пример кода панели навигации:

 <NavigationView x:Name="NavView" IsSettingsVisible="True"
                    ItemInvoked="NavView_ItemInvoked">

        <NavigationView.MenuItems>
            <NavigationViewItem Content="Начальная страница" Tag="home">
                <NavigationViewItem.Icon>
                    <FontIcon Glyph=""/>
                </NavigationViewItem.Icon>
            </NavigationViewItem>
            <NavigationViewItemSeparator/>
            <NavigationViewItemHeader Content="Новые возможности"/>
            <NavigationViewItem Icon="AllApps" Content="Автозагрузка" Tag="автозагрузка"/>
            <NavigationViewItem Icon="AllApps" Content="Перезапуск" Tag="перезапуск"/>
            <NavigationViewItem Icon="Video" Content="Color picker" Tag="color picker"/>
            <NavigationViewItem Icon="Audio" Content="Parallax" Tag="parallax"/>
            <NavigationViewItem Icon="Audio" Content="Другие контролы" Tag="другие"/>
        </NavigationView.MenuItems>

        <NavigationView.HeaderTemplate>
            <DataTemplate>
                <Grid Background="LightGray">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="Auto"/>
                        <ColumnDefinition/>
                    </Grid.ColumnDefinitions>
                    <TextBlock Style="{StaticResource TitleTextBlockStyle}"
                           FontSize="28"
                           VerticalAlignment="Center"
                           Margin="12,0"
                           Text="Это Header"/>
                    <CommandBar Grid.Column="1"
                            HorizontalAlignment="Right"
                            DefaultLabelPosition="Right">
                        <AppBarButton Label="Дополнителная кнопка" Icon="Refresh"/>
                    </CommandBar>
                </Grid>
            </DataTemplate>
        </NavigationView.HeaderTemplate>

        <NavigationView.PaneFooter>
            <Image Source="Assets/logo.png" Width="50" Height="50" />
        </NavigationView.PaneFooter>

        <Frame x:Name="ContentFrame">
            <Frame.ContentTransitions>
                <TransitionCollection>
                    <NavigationThemeTransition/>
                </TransitionCollection>
            </Frame.ContentTransitions>
        </Frame>

    </NavigationView>

Fall Creators Update: важное для программиста - 6

Обратите внимание, что есть возможность добавить вниз какие-нибудь произвольные контролы. В примере туда добавлена картинка (кубик над пунктом меню Settings/Настройки). Сам пункт меню Settings включается и выключается с помощью атрибута IsSettingsVisible.

В коде C# в событии NavView_ItemInvoked можно проверить была ли нажата кнопка Settings.

if (args.IsSettingsInvoked)
     {
         ContentFrame.Navigate(typeof(SettingsPage));
     }

Или же можно проверить содержимое args.InvokedItem, которое содержит в себе текст нажатого элемента пункта меню. Например, так:

  if (args.InvokedItem==”Начальная страница”)
     {
         ContentFrame.Navigate(typeof(HomePage));
     }

Более подробную информацию смотрите на официальной страничке документации [3].

Person Picture Control

Элемент управления, отображающий аватар и имя/инициалы пользователя. Довольно простой контрол.

Fall Creators Update: важное для программиста - 7

Добавить на страницу его можно с помощью следующего тега:

    <PersonPicture DisplayName="John Doe" Foreground="Black" ProfilePicture="Assetsjohndoe.jpg" Initials="JD" />

Его рекомендуется использовать для отображения аватарки текущего пользователя или какого-либо контакта.

Подробнее почитать о нем можно здесь [4].

Rating Control

С этим контролом тоже все должно быть понятно.

Fall Creators Update: важное для программиста - 8

Добавить на страницу можно следующим тегом:

    <RatingControl x:Name="MyRatings" />

Официальная документация тут [5].

Color Picker

Долгожданный контрол для выбора цвета.

Fall Creators Update: важное для программиста - 9

В следующем примере при изменении цвета в контроле автоматически меняется цвет фона (используется простая привязка или выражаясь иначе — биндинг).

     <Grid>
        <Grid.Background>
            <SolidColorBrush Color="{x:Bind myColorPicker.Color, Mode=OneWay}"/>
        </Grid.Background>
        <ColorPicker x:Name="myColorPicker" />
    </Grid>

Официальная документация [6]

Parallax

Неравномерное перемещение объектов при прокрутке позволяет создать эффект параллакса.

Fall Creators Update: важное для программиста - 10

Допустим у вас есть Grid внутри которого размещен какой-то элемент, содержимое которого не помещается на одной странице. И фоном в Grid добавлено какое-то изображение. Для того чтобы появился эффект параллакса необходимо изображение обернуть в тег Parallax, указав в качестве Source привязку к очень-очень длинному контенту.

В следующем примере ListView с именем ForegroundElement не умещается на экране. Фоном ему установлено изображение и при прокрутке возникнет красивый эффект.

<Grid>
        <ParallaxView Source="{x:Bind ForegroundElement}" VerticalShift="50">
            <!-- Фон -->
            <Image x:Name="BackgroundImage" Source="Assets/background.jpg"
               Stretch="UniformToFill"/>
        </ParallaxView>

        <ListView x:Name="ForegroundElement">
            <x:String>Item 1</x:String>
            <x:String>Item 2</x:String>
            <x:String>Item 3</x:String>
            <x:String>Item 4</x:String>
            <x:String>Item 5</x:String>
            <x:String>Item 6</x:String>
            <x:String>Item 7</x:String>
            <x:String>Item 8</x:String>
            <x:String>Item 9</x:String>
            <x:String>Item 10</x:String>
            <x:String>Item 11</x:String>
            <x:String>Item 13</x:String>
            <x:String>Item 14</x:String>
            <x:String>Item 15</x:String>
            <x:String>Item 16</x:String>
            <x:String>Item 17</x:String>
            <x:String>Item 18</x:String>
            <x:String>Item 19</x:String>
            <x:String>Item 20</x:String>
            <x:String>Item 21</x:String>
        </ListView>
    </Grid>

Подробнее читайте в документации Microsoft [7].

Swipe

Еще одним интересным контролом является SwipeControl. Возможно, что вы встречали его раньше в каких-либо приложениях. Он позволяет с помощью одноименного жеста открыть пункт меню. Жестом является движение пальца слева на право или наоборот. Посмотрите на следующий скриншот и вам станет понятнее о чем речь.

Fall Creators Update: важное для программиста - 11

INFO

Режим Reveal означает, что после жеста будет отображен пункт скрытый меню. Альтернативно можно установить режим Execute, который сразу же не только отобразит, но и выполнит действие меню.

На скриншоте изображен ListView, проведя по элементу которого пальцем можно открыть меню.
Давайте разберем код этого примера. Для того, чтобы он заработал в ресурсы страницы необходимо добавить следующий код:

<Page.Resources>
        <SymbolIconSource x:Key="DeleteIcon" Symbol="Delete" />

        <SwipeItems x:Key="ExecuteDelete" Mode="Reveal">
            <SwipeItem Text="Delete" IconSource="{StaticResource DeleteIcon}" Invoked="SwipeDeleteItem_Invoked" />
        </SwipeItems>
    </Page.Resources>

В нем мы создаем иконку с символом корзины и ключом «DeleteIcon». Далее создаем пункт меню Swipe с ключом «ExecuteDelete» и только что созданной иконкой. По нажатию на этот пункт меню будет вызвано событие SwipeDeleteItem_Invoked.

Теперь рассмотрим XAML код списка:

    <ListView x:Name="sampleList" Width="400" Height="300">
        <ListView.ItemTemplate>
            <DataTemplate x:DataType="x:String">
                <SwipeControl
                 RightItems="{StaticResource ExecuteDelete}">
                    <StackPanel Orientation="Vertical" Margin="5">
                        <TextBlock Text="{x:Bind}" FontSize="18"/>
                        <StackPanel Orientation="Horizontal">
                            <TextBlock Text="Lorem ipsum dolor sit amet, consectetur adipiscing elit..." FontSize="12"/>
                        </StackPanel>
                    </StackPanel>
                </SwipeControl>
            </DataTemplate>
        </ListView.ItemTemplate>
        <ListView.Items>
            <x:String>Demo item 1</x:String>
            <x:String>Demo item 2</x:String>
            <x:String>Demo item 3</x:String>
        </ListView.Items>
    </ListView>

Как вы можете заметить, в ListView добавлено 3 пункта с названиями «Demo item ..». Для простоты они добавлены прямо в список, но можно привязать ListView к какой-нибудь коллекции с помощью биндинга.

Самому списку назначен шаблон, в котором используется SwipeControl с ресурсом ExecuteDelete. Контрол будет отображен при жесте справа на лево так как используется атрибут RightItems.

Можно обойтись и без ListView. Например, так:

    <SwipeControl Width="400" Height="75"
          RightItems="{StaticResource ExecuteDelete}">
         <StackPanel Orientation="Vertical" Margin="5" Background="DarkGray">
             <TextBlock Text="Какой-нибудь заголовок" FontSize="18"/>
             <StackPanel Orientation="Horizontal">
                 <TextBlock Text="Lorem ipsum dolor sit amet, consectetur adipiscing elit..." FontSize="12"/>
             </StackPanel>
         </StackPanel>
     </SwipeControl>

Таким образом вы сможете добавить скрытое меню, отображаемое жестом, какому-нибудь элементу вашей страницы.

Официальная документация здесь [8].

Acrylic Material

Это даже не совсем элемент управления. Это кисть, которая довольно часто используется в интерфейсах. Меню «Пуск» в Fall Creators Update выполнено из акрила. Вот так выглядит стандартное приложение «Калькулятор» с фоном из акрилового материала:

Fall Creators Update: важное для программиста - 12

XAML код этой кисти может выглядеть примерно так:

<AcrylicBrush TintColor="#ED3462ED" TintOpacity="0.8" FallbackColor="#ADAFAFFF"/>

Больше информации найдете на сайте microsoft.com [9].

Reveal

Опять не контрол, а определенный световой эффект, который позволяет обратить внимание пользователя на тех объектах, которые находятся в фокусе курсора.

Fall Creators Update: важное для программиста - 13

Некоторые контролы поддерживают reveal по умолчанию. Это ListView, GridView, TreeView, NavigationView, AutosuggestBox, MediaTransportControl, CommandBar, ComboBox.

А на некотрых контролах этот эффект можно включить, указав особый стиль. Например, это можно указать кнопке:

    <Button Content="Button Content" Style="{StaticResource ButtonRevealStyle}"/>

Документация [10].

Еще одно улучшение в дизайнере XAML

Разумеется, что дизайнер Visual Studio позволяет отображать эти контролы и оптимизирован для их отображения. На следующем изображении вы можете увидеть, как в дизайнере отображен ресурс AcrylicBrush (Fall Creators Update опять слева).

Fall Creators Update: важное для программиста - 14

Почитать про улучшения XAML дизайнера на английском с кучей технических деталей и уточнений можно здесь: A significant update to the XAML Designer [11].

.NET Standard 2.0

Большим шагом вперед является поддержка .NET Standard 2.0. Но для него необходимо, чтобы у вашего проекта минимальной версией был установлена версия билда выше чем 1627. Зато теперь портировать код .NET Framework приложений на UWP станет гораздо проще.

Автозапуск приложения

Одной из самых интересных возможностей является возможность запускать приложение при запуске операционной системы. Раньше такая возможность была у Desktop Bridge приложений, но у UWP приложений ее не было.

Настроим манифест. Приложение должно использовать namespace контракт 5-ой версии:

    xmlns:uap5="http://schemas.microsoft.com/appx/manifest/uap/windows10/5"

И необходимо зарегистрировать расширение windows.startupTask.

    <uap5:Extension
    Category="windows.startupTask"
    Executable="App1.exe"
    EntryPoint="App1.App">
    <uap5:StartupTask
    TaskId="SomeIdThatIUseWithThisApp"
    Enabled="false"
    DisplayName="Name of Test App" />
    </uap5:Extension>

Иерархия манифеста следующая: Package Applications Application Extensions <uap5:Extension>

Зарегистрировать автозапуск приложения можно с помощью подобного кода:

    // Сначала проверяем состояние автозапуска. Получаем его в переменную startupTask
    StartupTask startupTask = await StartupTask.GetAsync("SomeIdThatIUseWithThisApp");
    switch (startupTask.State)
    {
        case StartupTaskState.Disabled:
            // В случае если автозапуск просто выключен пробуем его включить
            StartupTaskState newState = await startupTask.RequestEnableAsync();
           // в переменной newState будет получен результат того было ли включение автозапуска благополучным
            break;
        case StartupTaskState.DisabledByUser:
            // Здесь автоматически включить автозапуск не получится. Раз выключено пользователем, то значит он автоматически его не хочет включать…
            break;
        case StartupTaskState.DisabledByPolicy:
	// автозапуск выключен групповыми политиками или не поддерживается устройством
            break;
        case StartupTaskState.Enabled:
            // все уже включено :)
            break;
    }

Этот код требует добавления следующего пространства имен:

    using Windows.ApplicationModel;

INFO

По умолчанию после установки приложения автозапуск выключен.

Если ваше приложение поддерживает автозапуск, то вы можете перегрузить метод OnActivated и получить какие-то параметры. Примерно таким образом:

    protected override void OnActivated(IActivatedEventArgs args)
    {
    Frame rootFrame = Window.Current.Content as Frame;
    if (rootFrame == null)
    {
        rootFrame = new Frame();
        Window.Current.Content = rootFrame;
    }

    if (args.Kind == ActivationKind.StartupTask)
    { 
      // здесь вы можете получить аргументы автозапуска
        var startupArgs = args as StartupTaskActivatedEventArgs;
    }
 
    rootFrame.Navigate(typeof(MainPage));
    Window.Current.Activate();
    }

Почитать про этот функционал на английском можно здесь: Configure your app to start at log-in [12]

Перезапуск приложения

Еще одним, как говорится, «из той же серии» функционалом является возможность перезапуска приложения. Предполагается, что это может быть необходимо для перезапуска игры/приложения после обновления лицензии или установки какого-то дополнительного контента.

Делается перезапуск одной строчкой:

    AppRestartFailureReason result = await CoreApplication.RequestRestartAsync("строка с какими-нибудь параметрами, которые можно считать при активации приложения");

И добавлением пространства имен:

    using Windows.ApplicationModel.Core;

Возвращаемым значением переменной result может быть одно из значений APPRestartFailureReason [13]: NotInForeground, RestartPending, Other

WARNING

Перезапускаемое приложение должно быть видимым на момент перезапуска.

Еще есть возможность перезапустить приложение в контексте другого пользователя с помощью RequestRestartForUserAsync.

Пример перезапускающегося приложения находится по следующей ссылке Request Restart Sample [14].

Английский артикул тут: How to Restart your App Programmatically [15].

WWW

В результате того что я все попробовал на практике, у меня получилось простенькое и веселенькое приложение в котором используется перечисленный в этой статье функционал. Посмотреть его код вы можете по ссылке: GitHub репозиторий FallCreatorsApp [16].

В заключение, хотелось бы заметить, что не так давно вышел в свет UWP-шный WinDbg [17].

Обычные дебаггеры позволяют двигаться только вперед по времени выполнения кода. А у этого есть функционал под названием Time Travel Debugging (TTD), с помощью которой можно вернуться назад по процессу исполнения кода. Интересно, что код можно выполнить на определенной машине (именно на той, на которой возникает баг) и записать процесс исполнения кода. Будет создан trace файл с расширением .RUN. Этот файл можно проигрывать множество раз и анализировать.

Заключение

Напоминаю, что UWP приложения лучше олдскульных .NET-овских тем, что они более безопасны и их можно устанавливать/удалять бесчисленное количество раз не забивая систему/реестр различным мусором. Хотя и у классических дотнетовских приложений тоже пока что есть свои плюсы. Они практически неограничены в правах. Или же, например, могут работать в трее. Но скоро эти плюсы могут появиться и у UWP.

Напоминаем, что это полная версия статьи из журнала Хакер [18]. Ее автор — Алексей Соммер [19].

Автор: sahsAGU

Источник [20]


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/c-2/269533

Ссылки в тексте:

[1] официальной страницы: https://developer.microsoft.com/en-us/windows/downloads/windows-10-sdk

[2] Fluent: https://fluent.microsoft.com/

[3] страничке документации: https://docs.microsoft.com/en-us/windows/uwp/controls-and-patterns/navigationview

[4] здесь: https://docs.microsoft.com/en-us/windows/uwp/controls-and-patterns/person-picture

[5] тут: https://docs.microsoft.com/en-us/windows/uwp/controls-and-patterns/rating

[6] Официальная документация: https://docs.microsoft.com/en-us/windows/uwp/controls-and-patterns/color-picker

[7] документации Microsoft: https://docs.microsoft.com/en-us/windows/uwp/style/parallax

[8] здесь: https://docs.microsoft.com/en-us/windows/uwp/controls-and-patterns/swipe

[9] microsoft.com: https://docs.microsoft.com/en-us/windows/uwp/style/acrylic

[10] Документация: https://docs.microsoft.com/en-us/windows/uwp/style/reveal

[11] A significant update to the XAML Designer: https://blogs.msdn.microsoft.com/visualstudio/2017/09/11/a-significant-update-to-the-xaml-designer/

[12] Configure your app to start at log-in: https://blogs.windows.com/buildingapps/2017/08/01/configure-app-start-log/

[13] APPRestartFailureReason: https://docs.microsoft.com/en-us/uwp/api/windows.applicationmodel.core.apprestartfailurereason

[14] Request Restart Sample: https://github.com/Microsoft/AppModelSamples/tree/master/Samples/TestRestart

[15] How to Restart your App Programmatically: https://blogs.windows.com/buildingapps/2017/07/28/restart-app-programmatically/#SP3PCMD6VXoQAmVZ.97

[16] GitHub репозиторий FallCreatorsApp: https://github.com/programmersommer/FallCreatorsApp

[17] WinDbg: https://www.microsoft.com/en-us/store/p/windbg/9pgjgd53tn86

[18] статьи из журнала Хакер: https://xakep.ru/2017/10/27/fall-creators-update-uwp/

[19] Алексей Соммер: https://habrahabr.ru/users/asommer/

[20] Источник: https://habrahabr.ru/post/343240/