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



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

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

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



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



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

Navigation View


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



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



В режиме 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>



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

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

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

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

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

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

Person Picture Control


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



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

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

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

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

Rating Control


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



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

    <RatingControl x:Name="MyRatings" />

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

Color Picker


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



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

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

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

Parallax


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



Допустим у вас есть 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.

Swipe


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



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>

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

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

Acrylic Material


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



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

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

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

Reveal


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



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

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

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

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

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


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



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

.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

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


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

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

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

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

    using Windows.ApplicationModel.Core;

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

WARNING


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

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

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

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

WWW


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

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

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

Заключение


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

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

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


  1. denismaster
    30.11.2017 13:50

    Не планируются ли в будущем расширение поддерживаемых платформ? Например, поддержка Windows 7+, Mac OS, Linux?


    1. leschenko
      30.11.2017 14:13

      Я не из MS, но попробую угадать — нет. По крайней мере Windows 7 точно нет.


    1. Machine79
      30.11.2017 15:09

      Хахаха Хороший Вопрос!


    1. notacat
      30.11.2017 15:29

      ниже написала, даже с Windows 10 уже не все хорошо, куда уж расширяться


    1. kefirr
      01.12.2017 13:22

      Кросс-платформенный аналог WPF: https://github.com/AvaloniaUI/Avalonia
      Недавно пробовал, оно вполне себе работает на вин/линух/макос из-под .NET Core.


      1. expeon
        01.12.2017 22:54
        +1

        UWP ? WPF
        Статья и сабжевый вопрос ведь про UWP?


  1. Free_ze
    30.11.2017 15:18

    Напоминаем, что это полная версия статьи из журнала Хакер
    Забавно, что там она продается за деньги.


    1. sahsAGU Автор
      30.11.2017 16:01

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


  1. notacat
    30.11.2017 15:28

    с точки зрения разработчика все хорошо. Один вопрос. MS решили, что Creators Update не будет устанавливаться на машины, которые как-то там не совместимы по железу. У меня лично один ноут остался с Anniversary Update и дальше ему MS ничего не предлагает, кроме обновлений безопасности. Т.е. часть юзеров забанили по признаку железа. И нельзя же ожидать, что ради каких-то фич они немедленно бросятся новые компьютеры покупать. Они может и хотели бы, но предположим у кого-то денег нет. Получается, что если хочешь сделать приложение для всех — надо писать на каком-то старом SDK, где всего этого нет.
    ИМХО, какие-то очередные грабли


  1. fareloz
    30.11.2017 15:38

    Это, конечно вкусовщина, но калькулятор — идеальный пример неправильного использования акрила. Его слишком много, в итоге теряется фокус и читабельность


  1. aquamakc
    30.11.2017 15:56

    Стойкое ощущение, что это всё задумывалось для мобильных платформ, но по причине скоропостижного ухода Windows mobile в мир иной — преподносится, как технология для десктоп.


  1. zed220
    30.11.2017 15:59

    То, что сделали с калькулятором — это какой-то кошмар. Прозрачность появляется, если окно калькулятора активировано, и пропадает, когда нет. Работать мешает, т.к. на разноцветном фоне цифры и текст видно хуже. Пришлось поставить сторонний калькулятор.
    В общем, фича странная, зачем она нужна — не ясно. Было что-то подобное в Windows 7 с бордерами окошек, там это смотрелось интересно. Но в последующий версиях windows это убрали. И вот, как я понимаю, сейчас можно сделать что-то похожее. Но показывают почему-то прозрачный фон окна.


    1. notacat
      30.11.2017 19:34

      вроде бы где-то в системе можно это отключить


      1. fareloz
        01.12.2017 13:15

        Да, в настройках отключается. Но он отключается полностью в системе, а есть действительно удачные места, где акрил на своем месте.


        1. notacat
          01.12.2017 13:47

          да вот я сначала отключила. Потом подумала, что раз мы под UWP пишем — надо помучиться и понять. Включила обратно. Пока не нашла удачных мест. Скажите, что вам кажется хорошо, может я что-то пропускаю


          1. fareloz
            02.12.2017 12:27
            +1

            ИМХО панель управления музыкой в Грув Мьюзик и Панель в галереи


  1. sumanai
    30.11.2017 16:11

    Никогда бы не подумал, что можно так испохабить калькулятор. Он и раньше то был ужасен, а сейчас просто нет слов для описания его убожества.
    Калькулятор в XP/7 был идеальным, не пойму, зачем они его полезли «улучшать». Лучше бы ядро пилили.


    1. notacat
      30.11.2017 19:34

      потому что самое простое приложение, идеально для демонстрации новых фич


  1. TargetSan
    30.11.2017 16:50

    Вопрос к аудитории. Приложения на UWP хоть кто-то использует в природе? У меня стабильное впечатление "технология ради технологии".


    1. BlackDizel
      30.11.2017 17:04

      на ноутбуке-трансформере win10 И linux mint. Работаю в mint, но видео просматриваю в стандартном UWP плеере—меньше греется ноутбук


    1. sumanai
      30.11.2017 17:08

      Ну, в этом обновлении убунта, как и другие люнуксы, ставятся из магазина и прописаны там же, так что можно сказать, что даже я использовал UWP ))


    1. gunt3er
      30.11.2017 17:22

      Сразу удаляю все через Powershell. Даже Edge и магазин. Бестолковые ИМХО.


    1. notacat
      30.11.2017 19:36

      у меня есть Lumia от MS, там только такие приложения. Вполне меня устраивает, возможно на планшетах тоже удобно. На десктопе конечно лучше десктопными пользоваться


    1. dmitry_dvm
      30.11.2017 23:55
      +1

      На ноуте-трансформере использую только их. Обычные десктоные приложения не годятся для тачскрина. Да и в остальном стараюсь только их использовать, т.к. обновляются в фоне, жрут мало, работают быстро. Контролы крупные, опять же. Да и на hidpi значительно приятнее смотрятся. У тинькова uwp-клиент вообще прекрасен. Да любой uwp-клиент любого сервиса значительно удобнее сайта с нынешними тоннами жс.


  1. rum
    30.11.2017 19:15

    можно устанавливать/удалять бесчисленное количество раз не забивая систему/реестр различным мусором

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


  1. dmitry_dvm
    01.12.2017 00:05

    Раздражает, что контролы продолжают писать в расчете на codebehind. Им кто-то пользуется в коммерческой разработке? Почему у кнопок и всяких там гипелинк-баттонов есть искаробки привязка к командам, а у остального приходится бихевиорами обмазываться? Сейчас хоть запилили экстеншн к listview и то полегче стало. А взять контрол InAppNotification из Community Toolkit — так он тупо только для codebehind, чтобы привязать к мввм надо корячиться черт знает как.
    А еще почему-то доки все стали по-английски. Все было на русском, а сейчас вдруг недоступно на вашем языку. Со временем мс начинает бесить бесконечным бардаком. Подумываю уйти в бэкенд уже. Кому-нибудь нужен asp.net core разраб со знанием XAML и всего этого мобильно-десктопного счастья?


    1. rum
      01.12.2017 02:08

      я позволю себе вольность и задам вопрос вашей же цитатой:

      Все было на русском

      Им кто-то пользуется в коммерческой разработке?

      я ничего не имею против родного языка, но по-моему адекватная документация — только на английском, в переводе что-нибудь да пострадает (тем более, как это часто бывает, в машинном варианте).


    1. wlbm_onizuka
      01.12.2017 08:04

      Раздражает, что контролы продолжают писать в расчете на codebehind

      Не пользуюсь ни codebehind ни MVVM ни богомерзким XAML. Создаю UI в коде. Счастлив.


      1. aquamakc
        01.12.2017 09:26

        ) старовер?


        1. wlbm_onizuka
          01.12.2017 10:29

          Вовсе нет, попробовал все и пришел к такому варианту.
          Разметка на Xaml провалилась также как в свое время визуальное программирование. Xaml не является языком программирования, как C#, он ограничен и создает проблемы которые потом героически решаются.
          Это просто мнение, оно может быть полезно тем кто чувствует то же, но пока сомневается :)


          1. aquamakc
            01.12.2017 10:31

            Xaml не является языком программирования

            ну да. XAML — язык разметки, как HTML. Читал, что Микрософт вводом XAML хотела разделить обязанности дизайнера и программиста.


          1. notacat
            01.12.2017 13:55

            вы просто не умеете его готовить


      1. kefirr
        01.12.2017 13:19

        И это работает в десятки раз быстрее.
        Когда работал с WPF, стандартный подход к оптимизации, например, тяжелого DataTemplate в больших списках — перейти от XAML к аналогичному коду на C#.


        1. wlbm_onizuka
          01.12.2017 13:37

          Там есть какие-то хитрости с XAML, который по-умолчанию встраивается в сборку в виде BAML (бинарно сериализованный), а можно заставить его стать CAML (компилированный). Сам не пробовал, но кажется это тоже может помочь.


        1. notacat
          01.12.2017 13:59

          смотря что вы делаете в xaml, и смотря что вы делаете в коде. Испортить можно абсолютно все. Xaml хорош, когда вам надо поддерживать произвольный контент. В одном списке вы хотите показать просто текст, а в другом — кнопки с картинками. Код может быть один, а xaml разный. Писать эту разницу в коде? За счет чего оно будет быстрее?


          1. kefirr
            01.12.2017 14:20

            Не очень понял этот комментарий.


            • XAML — это просто представление объектной иерархии. Всё, что можно выразить в XAML, можно выразить и в C# (но не наоборот).
            • XAML/BAML нужно в рантайме превратить в дерево объектов, это дороже, чем выполнить скомпилированный C# код (про CAML не в курсе, может, он решает проблему).

            XAML декларативный, и он удобнее для описания UI, с этим спору нет. Но в профайлере явно видно, на что уходит время при загрузке развесистых контролов.


            1. wlbm_onizuka
              01.12.2017 14:41

              он удобнее для описания UI
              Он удобнее для описания UI только потому что система классов WPF дизайнилась под работу с XAML. Кроме того в сложных случаях код все равно удобнее, и это именно та причина по которой я отказался от XAML.
              Проблемы производительности это вообще отдельный вопрос, наверняка майкрософт мог бы оптимизировать до преемлемого уровня. Но вот декларативную природу XAML оптимизировать для сложных случаев все равно не выйдет.


            1. notacat
              01.12.2017 16:08

              это очень зависит от конкретного юз-кейза. Т.е. в одном случае может быть так, а в другом — наоборот. Зависит от того, как используются байндинги, как переключаются состояния и т.д. Т.е. например можно менять видимость чего-то с помощью байндинга к какому-то свойству, а можно — через VisualStates. Можно сделать хороший темплейт для ячейки грида в xaml, который будет загружаться всего один раз за время жизни приложения и кэшироваться, и при тяжелом UI это может быть быстрее, чем делать то же самое в коде. Ну и т.д. Т.е. тут нет общего решения. Каждый конкретный случай надо смотреть в профайлере. И смотреть не просто развесистые контролы, а в том числе каждую их мелкую часть отдельно.
              Или например анимации выполняются на GPU, и это обычно быстрее, чем менять какие-то свойства из кода. Хотя можно и анимации в коде делать, но тут большой разницы не будет, чтобы заморачиваться.


              1. wlbm_onizuka
                02.12.2017 08:56
                +1

                XAML это абстракция над кодом, как любая абстракция он имеет свою цену. Вариант на XAML всегда будет только медленее чем вариант в коде. Иногда значительно, иногда нет.


                1. notacat
                  02.12.2017 16:32
                  +1

                  ооо. Вы вообще в курсе, как это в рантайме работает? Рантайму вообще все равно, что над чем абстракция. Ему существенно, сделали ли вы так, чтобы тяжелая работа выполнялась видеокартой, или все на CPU повесили. И насколько сложный лейаут. А в коде это сделано или в замле — какая разница-то?


                  1. wlbm_onizuka
                    02.12.2017 19:48

                    рантайму не все равно, читайте выше что пишет kefirr

                    XAML/BAML нужно в рантайме превратить в дерево объектов, это дороже, чем выполнить скомпилированный C# код

                    каждое создание контрола, описанного в XAML в рантайме приводит к парсингу его BAML, это доооолго
                    CPU и GPU вообще к теме не относится


                    1. notacat
                      02.12.2017 20:15
                      +1

                      угу, а из c# кода вы конечно же никакое дерево объектов не создаете, а только рисуете как в винформах. Дураки платформу-то делали, не догадывались до этого


                      1. wlbm_onizuka
                        03.12.2017 02:59

                        Долго не дерево создается, а долго BAML парсится, когда в коде создаешь контролы этого не происходит.
                        Но разговор был не о производительности, а о сложности разработки не тривиального UI на XAML и в коде.
                        Я все свои аргументы уже изложил, не хочу холиварить и повторяться, так что удаляюсь из обсуждения)


                        1. notacat
                          03.12.2017 14:12

                          когда в коде создаешь — долго перемещается в другое место, вот и все. Расходы на парсинг замла сравнительно со всем остальным — это копейки. Хотя конечно это зависит от кривизны рук и степени понимания, как надо работать с замлом.
                          Без конкретных примеров холиварить нет смысла, да.


      1. HellMaster_HaiL
        01.12.2017 14:45

        А зачем Вам тогда WPF?
        OnPaint() и вперёд.


  1. fedorro
    01.12.2017 11:14

    А когда ждать поддержки длинных путей, в 4th Millennium Update? Уже везде они давно поддерживаются, но нет, скачанный файл Explorer-ом не переместить, в Visual Studio TFS-проекты в корень диска приходится мапить, чтобы все файлы выкачались, даже если у кого-то ещё проекты смаплены в корне. Директория с пробелом в конце (или в начале) — тоже неподъемная, задача, Total Commander не спасает, хотя такие директории создает Office при установке.
    Надо базовые функции до ума довести, а уж потом красивости, свайпики, рюшечки делать.


  1. petuhov_k
    02.12.2017 17:20
    +1

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

    Первый раз за последние, наверное, лет 15 я словил access violation именно при разработке UWP приложения. Причём в очень простом сценарии. Пришлось городить костыль, чтобы его избежать.