Летающие панельки от нас улетели… О навигации и кнопке «Назад» в C#/XAML приложениях Windows 10


    Если вы захотите вынести настройки своего приложения UWP в «летающую панельку» Flyout, то я вас огорчу. Летающие панельки точно так же как и «волшебные Charm панельки» ушли в прошлое и теперь вместо них необходимо использовать другой способ отображения информации – навигацию. Про то, что и как читайте дальше

    Сейчас в Windows 10 все еще можно увидеть «летающую панельку» даже в интерфейсе самой системы. Взять, к примеру, «Центр уведомлений»:



    Однако, при разработке нового универсального приложения контрол «из коробки» уже отсутствует. Вот такой элемент управления можно было добавить в приложение Windows 8.1



    Сейчас, в связи с тем, что приложения Windows 10 стали универсальными и аналог «летающей панельки» Flyout для мобильных устройств отсутствует, нам предлагается замена в виде навигации и меню гамбургера

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



    Для тех, кому любопытно, XAML код примера скрыт под спойлером:

    Открыть код
    <Button HorizontalAlignment="Center" Margin="0,125,0,0" x:Name="buttonWithFlyout" Content="Открыть FlyOut">
                <Button.Flyout>
                    <Flyout>
                        <StackPanel>
                            <TextBlock>Текст Текст Текст Текст и что-нибудь полезное</TextBlock>
                            <Button Click="VeryImportantButton_Click" Margin="0,5,0,0">
                               Очень полезная кнопка
                            </Button>
                            <TextBlock>и еще какой-нибудь текст</TextBlock>
                        </StackPanel>
                    </Flyout>
                </Button.Flyout>
     </Button>
    


    Для того чтобы FlyOut был отображен после клика не нужно реализовывать событие Click и добавлять какой-то код C#. Достаточно того, что FlyOut привязан к кнопке (является дочерним элементом).

    Но речь пойдет не о нем, а о том как сделать навигацию на страницу настроек и добавить кнопку «Назад». Сначала создадим страницу с настройками: Меню «Проект» — «Добавить новый элемент»:



    Выбираем элемент типа «Пустая страница». Я решил назвать страницу именем SettingsPage.xaml.

    Теперь нам нужно добавить кнопку перехода на эту страницу с настройками. Я решил для этого создать TopAppBar и добавить в него CommandBar с кнопочкой. Код XAML такой:

        <Page.TopAppBar>
            <CommandBar IsOpen="False" ClosedDisplayMode="Minimal">
                <CommandBar.PrimaryCommands>
        <AppBarButton x:Name="btnSettings" Label="Настройки" Click="btnSettings_Click" Icon="Setting"  >
                    </AppBarButton>
                </CommandBar.PrimaryCommands>
            </CommandBar>
        </Page.TopAppBar>
    

    В закрытом виде AppTopBar с кнопкой будет таким:



    А в открытом виде:



    Теперь нужно реализовать событие btnSettings_Click. Оно довольно простое:

            private void btnSettings_Click(object sender, RoutedEventArgs e)
            {
                this.Frame.Navigate(typeof(SettingsPage));
            }
    

    Бамс… И после нажатия кнопки мы переходим на страницу SettingsPage.xaml. Но вот вернуться назад у нас не получится.

    Для того чтобы была возможность возвратится на последнюю страницу, можно добавить кнопку «Назад». Предлагаю воспользоваться следующим сниппетом, который я опишу далее. Открываем App.xaml.cs и добавляем ссылку на пространство имен:

    using Windows.UI.Core;
    

    В конец метода void OnLaunched после объявления и инициализации rootFrame и всякого другого кода добавляем регистрацию двух событий:

     rootFrame.Navigated += OnNavigated;
     SystemNavigationManager.GetForCurrentView().BackRequested += OnBackRequested;
    

    Это событие перехода на текущую страницу и событие запроса перехода на предыдущую страницу. В событии OnNavigated мы, используя conditional operator, отобразим кнопку «Назад» или скроем ее в зависимости от того есть ли возможность перейти на страницу назад или нет:

            private void OnNavigated(object sender, NavigationEventArgs e)
            {
                // каждый раз когда загружаем страницу мы отображаем или скрываем кнопку
                SystemNavigationManager.GetForCurrentView().AppViewBackButtonVisibility =
                ((Frame)sender).CanGoBack ? AppViewBackButtonVisibility.Visible : AppViewBackButtonVisibility.Collapsed;
            }
    

    В событии запроса перехода назад, которое возникает при нажатии на BackButton мы вернемся на последнюю страницу с помощью rootFrame.GoBack();

            private void OnBackRequested(object sender, BackRequestedEventArgs e)
            {
                Frame rootFrame = Window.Current.Content as Frame;
    
                if (rootFrame.CanGoBack)
                {
                    e.Handled = true;
                    rootFrame.GoBack();
                }
            }
    

    Казалось бы, проверка на if (rootFrame.CanGoBack) здесь не совсем обязательна, так как мы отображаем кнопку «Назад» только в случае, если есть возможность перейти назад. Но еще может быть нажата и аппаратная кнопка на телефоне, так что пусть остается.
    В результате при переходе на страницу настроек получим такую вот кнопку в верхнем левом углу:



    Исходный код примера доступен на GitHub.

    UPDATE: Отличной альтернативой для отображения настроек приложения может стать PopUp или окошко ContentDialog:

    Но об этом уже в другой статье.
    • +14
    • 18,1k
    • 7
    Поделиться публикацией

    Комментарии 7

      +8
      Стремительно меняющиеся Design Guides на новых поколениях Windows отбивают охоту писать под нее приложения. Все равно через год подход признают устраевшим. Оно как бы и нормально — развитие, все дела, но почему-то они преподносят все в манере «вы все делали неправильно, и теперь правильно раз и навсегда, волшебно и невероятно — вот так»

      Чувствуешь как твое потраченное на изучение время спущено в унитаз.
          0
          вы забыли прикрепить кошмар версий 2.х.х, когда каждый лепил дизайн как умел
            0
            Я просто не нашел ссылок на гайдлайны. Хотя помню, как для простенького приложения под, кажется, 2.2, 2.3 и 3.0 приходилось делать три набора иконок для нотификаций, отличающихся даже пропорциями.
        0
        Простите, но аналог летающих панелек в мобильной версии отсутствует только потому что там сами летающие панельки есть.
        Они прекраснно работали и в 8.1, и продолжают работать в 10.
          0
          Контрол FlyOut в UWP есть, но вот вылетающей сбоку панельки out of box нет. Если на мобильнике вылезет сбоку такая панель, то она закроет собой весь экран. Довольно неудобное решение для мобильников. Хотя на десктопе или планшете оно смотрится отлично и в работе удобно. Но так как сейчас создаются универсальные приложения, то необходим универсальный интерфейс, который будет удобен везде.
            0
            Тогда каюсь. Я Вас неправильно понял.
            Я думал вы об этом:
            image
            Это есть.

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

        Самое читаемое