Pull to refresh

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

Reading time 3 min
Views 19K

Если вы захотите вынести настройки своего приложения 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:

Но об этом уже в другой статье.
Tags:
Hubs:
+14
Comments 7
Comments Comments 7

Articles