Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Важные API: класс Windows.UI.Xaml.Controls.Frame , класс Windows.UI.Xaml.Controls.Page , пространство имен Windows.UI.Xaml.Navigation , OnNavigatedTo
Чтобы реализовать обратную навигацию в приложении, поместите кнопку "Назад" в левом верхнем углу пользовательского интерфейса приложения. Пользователь ожидает, что кнопка "Назад" перейдет к предыдущему расположению в журнале навигации приложения. По умолчанию элемент управления Frame записывает действия навигации в BackStack и ForwardStack. Однако вы можете изменить, какие действия навигации добавляются в журнал навигации.
Для большинства приложений с несколькими страницами рекомендуется использовать элемент управления NavigationView для предоставления платформы навигации для приложения. Он адаптируется к различным размерам экрана и поддерживает как верхний стиль навигации, так и левый стиль навигации. Если ваше приложение использует элемент управления NavigationView, вы можете использовать встроенную кнопку «Назад» NavigationView.
Замечание
Рекомендации и примеры, приведенные в этой статье, должны использоваться при реализации навигации без использования NavigationView элемента управления. Если вы используете NavigationView, эта информация предоставляет полезные фоновые знания, но вам следует воспользоваться конкретными рекомендациями и примерами в статье NavigationView.
Кнопка "Назад"
Чтобы создать кнопку назад, используйте элемент управления Button с NavigationBackButtonNormalStyle стилем и поместите кнопку в левом верхнем углу пользовательского интерфейса приложения (дополнительные сведения см. в примерах кода XAML ниже).
<Page>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Button x:Name="BackButton"
Style="{StaticResource NavigationBackButtonNormalStyle}"
IsEnabled="{x:Bind Frame.CanGoBack, Mode=OneWay}"
ToolTipService.ToolTip="Back"/>
</Grid>
</Page>
Если в приложении есть верхняя панель commandBar, поместите Button элемент управления в CommandBar.Content область.
<Page>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<CommandBar>
<CommandBar.Content>
<Button x:Name="BackButton"
Style="{StaticResource NavigationBackButtonNormalStyle}"
IsEnabled="{x:Bind Frame.CanGoBack, Mode=OneWay}"
ToolTipService.ToolTip="Back"
VerticalAlignment="Top"/>
</CommandBar.Content>
<AppBarButton Icon="Delete" Label="Delete"/>
<AppBarButton Icon="Save" Label="Save"/>
</CommandBar>
</Grid>
</Page>
Чтобы свести к минимуму изменения в элементах пользовательского интерфейса в вашем приложении, отображайте неактивную кнопку "назад", если в "backstack" отсутствуют элементы (IsEnabled="{x:Bind Frame.CanGoBack, Mode=OneWay}"). Однако если вы ожидаете, что приложение никогда не будет иметь backstack, вам не нужно отображать кнопку назад вообще.
Оптимизация для различных устройств и входных данных
Это обратное руководство по проектированию навигации применимо ко всем устройствам, но ваши пользователи получат выгоду, если вы оптимизируете различные форм-факторы и методы ввода. Мы рекомендуем обрабатывать следующие события (в дополнение к нажатию кнопки "Назад") для поддержки наиболее распространенных входных данных для обратной навигации.
| Событие | Ввод |
|---|---|
| CoreDispatcher.AcceleratorKeyActivated | ALT+СТРЕЛКА ВЛЕВО, VirtualKey.GoBack (ВиртуальнаяКлавиша.Назад) |
| SystemNavigationManager.BackRequested | Windows + Backspace, Кнопка "Геймпад B", Кнопка "Назад в режиме планшета", Аппаратная кнопка "Назад" |
| CoreWindow.PointerPressed | Виртуальная клавиша XButton1 (Например, кнопка "Назад", найденная на некоторых мышах.) |
Примеры кода
В этом разделе показано, как обрабатывать обратную навигацию с помощью различных входных данных.
Кнопка "Назад" и навигация назад
Как минимум, необходимо обработать событие кнопки "Назад" Click и предоставить код для выполнения обратной навигации. Вы также должны отключить кнопку "Назад", когда backstack пуст.
В этом примере кода показано, как реализовать поведение обратной навигации с помощью кнопки "Назад". Код реагирует на событие Button Click для навигации. Кнопка "Назад" включена или отключена в методе OnNavigatedTo , который вызывается при переходе на новую страницу.
Код показан для MainPage, но вы добавляете этот код на каждую страницу, которая поддерживает обратную навигацию. Чтобы избежать дублирования, можно поместить связанный с навигацией код в класс App на странице App.xaml.* кода.
<!-- MainPage.xaml -->
<Page x:Class="AppName.MainPage">
...
<Button x:Name="BackButton" Click="BackButton_Click"
Style="{StaticResource NavigationBackButtonNormalStyle}"
IsEnabled="{x:Bind Frame.CanGoBack, Mode=OneWay}"
ToolTipService.ToolTip="Back"/>
...
<Page/>
Код программной части:
// MainPage.xaml.cs
private void BackButton_Click(object sender, RoutedEventArgs e)
{
App.TryGoBack();
}
// App.xaml.cs
//
// Add this method to the App class.
public static bool TryGoBack()
{
Frame rootFrame = Window.Current.Content as Frame;
if (rootFrame.CanGoBack)
{
rootFrame.GoBack();
return true;
}
return false;
}
// MainPage.h
#include "App.h"
namespace winrt::AppName::implementation
{
struct MainPage : MainPageT<MainPage>
{
MainPage();
void MainPage::BackButton_Click(IInspectable const&, RoutedEventArgs const&)
{
App::TryGoBack();
}
};
}
// App.h
#include "winrt/Windows.UI.Core.h"
#include "winrt/Windows.System.h"
#include "winrt/Windows.UI.Input.h"
#include "winrt/Windows.UI.Xaml.Input.h"
using namespace winrt;
using namespace Windows::Foundation;
using namespace Windows::UI::Core;
using namespace Windows::UI::Input;
using namespace Windows::UI::Xaml;
using namespace Windows::UI::Xaml::Controls;
struct App : AppT<App>
{
App();
// ...
// Perform back navigation if possible.
static bool TryGoBack()
{
Frame rootFrame{ nullptr };
auto content = Window::Current().Content();
if (content)
{
rootFrame = content.try_as<Frame>();
if (rootFrame.CanGoBack())
{
rootFrame.GoBack();
return true;
}
}
return false;
}
};
Поддержка ключей доступа
Поддержка клавиатуры является неотъемлемой частью обеспечения отличной работы ваших приложений для пользователей с различными навыками, способностями и ожиданиями. Рекомендуется поддерживать клавиши акселератора для навигации вперёд и назад, так как пользователи, которые полагаются на них, будут ожидать обеих. Дополнительные сведения см. в разделе взаимодействия с клавиатурой и клавиатурные ускорители.
Распространенные клавиши акселератора для навигации вперед и назад: ALT+СТРЕЛКА ВПРАВО (вперед) и ALT+СТРЕЛКА ВЛЕВО (назад). Чтобы поддерживать эти клавиши для навигации, обработайте событие CoreDispatcher.AcceleratorKeyActivated. Вы обрабатываете событие, которое находится непосредственно в окне (а не элемент на странице), поэтому приложение реагирует на клавиши акселератора независимо от того, какой элемент имеет фокус.
Добавьте код в App класс для поддержки клавиш акселератора и навигации вперед, как показано здесь. (Предполагается, что предыдущий код для поддержки кнопки "Назад" уже добавлен.) Весь код App можно просмотреть вместе в конце раздела "Примеры кода".
// App.xaml.cs
// Add event handler in OnLaunched.
protected override void OnLaunched(LaunchActivatedEventArgs e)
{
// ...
// Do not repeat app initialization when the Window already has content,
// just ensure that the window is active
if (rootFrame == null)
{
// ...
// rootFrame.NavigationFailed += OnNavigationFailed;
// Add support for accelerator keys.
// Listen to the window directly so the app responds
// to accelerator keys regardless of which element has focus.
Window.Current.CoreWindow.Dispatcher.AcceleratorKeyActivated +=
CoreDispatcher_AcceleratorKeyActivated;
// ...
}
}
// ...
// Add this code after the TryGoBack method added previously.
// Perform forward navigation if possible.
private bool TryGoForward()
{
Frame rootFrame = Window.Current.Content as Frame;
if (rootFrame.CanGoForward)
{
rootFrame.GoForward();
return true;
}
return false;
}
// Invoked on every keystroke, including system keys such as Alt key combinations.
// Used to detect keyboard navigation between pages even when the page itself
// doesn't have focus.
private void CoreDispatcher_AcceleratorKeyActivated(CoreDispatcher sender, AcceleratorKeyEventArgs e)
{
// When Alt+Left are pressed navigate back.
// When Alt+Right are pressed navigate forward.
if (e.EventType == CoreAcceleratorKeyEventType.SystemKeyDown
&& (e.VirtualKey == VirtualKey.Left || e.VirtualKey == VirtualKey.Right)
&& e.KeyStatus.IsMenuKeyDown == true
&& !e.Handled)
{
if (e.VirtualKey == VirtualKey.Left)
{
e.Handled = TryGoBack();
}
else if (e.VirtualKey == VirtualKey.Right)
{
e.Handled = TryGoForward();
}
}
}
// App.cpp
void App::OnLaunched(LaunchActivatedEventArgs const& e)
{
// ...
// Do not repeat app initialization when the Window already has content,
// just ensure that the window is active
if (rootFrame == nullptr)
{
// ...
// rootFrame.NavigationFailed({ this, &App::OnNavigationFailed });
// Add support for accelerator keys.
// Listen to the window directly so the app responds
// to accelerator keys regardless of which element has focus.
Window::Current().CoreWindow().Dispatcher().
AcceleratorKeyActivated({ this, &App::CoreDispatcher_AcceleratorKeyActivated });
// ...
}
}
// App.h
struct App : AppT<App>
{
App();
// ...
// Add this code after the TryGoBack method added previously.
private:
// Perform forward navigation if possible.
bool TryGoForward()
{
Frame rootFrame{ nullptr };
auto content = Window::Current().Content();
if (content)
{
rootFrame = content.try_as<Frame>();
if (rootFrame.CanGoForward())
{
rootFrame.GoForward();
return true;
}
}
return false;
}
// Invoked on every keystroke, including system keys such as Alt key combinations.
// Used to detect keyboard navigation between pages even when the page itself
// doesn't have focus.
void CoreDispatcher_AcceleratorKeyActivated(CoreDispatcher const& /* sender */, AcceleratorKeyEventArgs const& e)
{
// When Alt+Left are pressed navigate back.
// When Alt+Right are pressed navigate forward.
if (e.EventType() == CoreAcceleratorKeyEventType::SystemKeyDown
&& (e.VirtualKey() == Windows::System::VirtualKey::Left || e.VirtualKey() == Windows::System::VirtualKey::Right)
&& e.KeyStatus().IsMenuKeyDown
&& !e.Handled())
{
if (e.VirtualKey() == Windows::System::VirtualKey::Left)
{
e.Handled(TryGoBack());
}
else if (e.VirtualKey() == Windows::System::VirtualKey::Right)
{
e.Handled(TryGoForward());
}
}
}
};
Обработка системных обратных запросов
Устройства Windows предоставляют различные способы, с помощью которых система может передать запрос обратной навигации в ваше приложение. Некоторые распространенные способы : кнопка B на геймпаде, клавиша Windows + клавиша Backspace или кнопка "Назад" в режиме планшета; Точные доступные параметры зависят от устройства.
Вы можете поддерживать системные запросы назад от аппаратных и программных клавиш, регистрируя слушателя для события SystemNavigationManager.BackRequested.
Ниже приведен код, добавленный в App класс для поддержки системных обратных запросов. (Предполагается, что предыдущий код для поддержки кнопки "Назад" уже добавлен.) Весь код App можно просмотреть вместе в конце раздела "Примеры кода".
// App.xaml.cs
// Add event handler in OnLaunced.
protected override void OnLaunched(LaunchActivatedEventArgs e)
{
// ...
// Do not repeat app initialization when the Window already has content,
// just ensure that the window is active
if (rootFrame == null)
{
// ...
// Add support for accelerator keys.
// ... (Previously added code.)
// Add support for system back requests.
SystemNavigationManager.GetForCurrentView().BackRequested
+= System_BackRequested;
// ...
}
}
// ...
// Handle system back requests.
private void System_BackRequested(object sender, BackRequestedEventArgs e)
{
if (!e.Handled)
{
e.Handled = TryGoBack();
}
}
// App.cpp
void App::OnLaunched(LaunchActivatedEventArgs const& e)
{
// ...
// Do not repeat app initialization when the Window already has content,
// just ensure that the window is active
if (rootFrame == nullptr)
{
// ...
// Add support for accelerator keys.
// ... (Previously added code.)
// Add support for system back requests.
SystemNavigationManager::GetForCurrentView().
BackRequested({ this, &App::System_BackRequested });
// ...
}
}
// App.h
struct App : AppT<App>
{
App();
// ...
private:
// ...
// Handle system back requests.
void System_BackRequested(IInspectable const& /* sender */, BackRequestedEventArgs const& e)
{
if (!e.Handled())
{
e.Handled(TryGoBack());
}
}
};
Поведение резервного копирования системы для обратной совместимости.
Ранее приложения UWP использовали SystemNavigationManager.AppViewBackButtonVisibility для отображения или скрытия системной кнопки обратной навигации. (Эта кнопка вызывает событие SystemNavigationManager.BackRequested .) Этот API будет поддерживаться для обеспечения обратной совместимости, но мы больше не рекомендуем использовать кнопку "Назад", предоставленную AppViewBackButtonVisibility. Вместо этого следует указать собственную кнопку "Назад в приложении", как описано в этой статье.
Если вы используете AppViewBackButtonVisibility, системный пользовательский интерфейс отрисовывает системную кнопку "Назад" в строке заголовка. (Внешний вид и взаимодействие пользователей для кнопки "Назад" не изменилось из предыдущих сборок.)
Обработка кнопок навигации мыши
Некоторые мыши предоставляют аппаратные кнопки навигации для перемещения вперед и назад. Эти кнопки мыши можно поддерживать, обрабатывая событие CoreWindow.PointerPressed и проверяя наличие IsXButton1Pressed (назад) или IsXButton2Pressed (вперед).
Ниже приведен код, добавленный в App класс для поддержки навигации по кнопке мыши. (Предполагается, что предыдущий код для поддержки кнопки "Назад" уже добавлен.) Весь код App можно просмотреть вместе в конце раздела "Примеры кода".
// App.xaml.cs
// Add event handler in OnLaunced.
protected override void OnLaunched(LaunchActivatedEventArgs e)
{
// ...
// Do not repeat app initialization when the Window already has content,
// just ensure that the window is active
if (rootFrame == null)
{
// ...
// Add support for system back requests.
// ... (Previously added code.)
// Add support for mouse navigation buttons.
Window.Current.CoreWindow.PointerPressed += CoreWindow_PointerPressed;
// ...
}
}
// ...
// Handle mouse back button.
private void CoreWindow_PointerPressed(CoreWindow sender, PointerEventArgs e)
{
// For this event, e.Handled arrives as 'true'.
if (e.CurrentPoint.Properties.IsXButton1Pressed)
{
e.Handled = !TryGoBack();
}
else if (e.CurrentPoint.Properties.IsXButton2Pressed)
{
e.Handled = !TryGoForward();
}
}
// App.cpp
void App::OnLaunched(LaunchActivatedEventArgs const& e)
{
// ...
// Do not repeat app initialization when the Window already has content,
// just ensure that the window is active
if (rootFrame == nullptr)
{
// ...
// Add support for system back requests.
// ... (Previously added code.)
// Add support for mouse navigation buttons.
Window::Current().CoreWindow().
PointerPressed({ this, &App::CoreWindow_PointerPressed });
// ...
}
}
// App.h
struct App : AppT<App>
{
App();
// ...
private:
// ...
// Handle mouse forward and back buttons.
void CoreWindow_PointerPressed(CoreWindow const& /* sender */, PointerEventArgs const& e)
{
// For this event, e.Handled arrives as 'true'.
if (e.CurrentPoint().Properties().IsXButton1Pressed())
{
e.Handled(!TryGoBack());
}
else if (e.CurrentPoint().Properties().IsXButton2Pressed())
{
e.Handled(!TryGoForward());
}
}
};
Весь код, добавленный в класс App
// App.xaml.cs
//
// (Add event handlers in OnLaunched override.)
protected override void OnLaunched(LaunchActivatedEventArgs e)
{
// ...
// Do not repeat app initialization when the Window already has content,
// just ensure that the window is active
if (rootFrame == null)
{
// ...
// rootFrame.NavigationFailed += OnNavigationFailed;
// Add support for accelerator keys.
// Listen to the window directly so the app responds
// to accelerator keys regardless of which element has focus.
Window.Current.CoreWindow.Dispatcher.AcceleratorKeyActivated +=
CoreDispatcher_AcceleratorKeyActivated;
// Add support for system back requests.
SystemNavigationManager.GetForCurrentView().BackRequested
+= System_BackRequested;
// Add support for mouse navigation buttons.
Window.Current.CoreWindow.PointerPressed += CoreWindow_PointerPressed;
// ...
}
}
// ...
// (Add these methods to the App class.)
public static bool TryGoBack()
{
Frame rootFrame = Window.Current.Content as Frame;
if (rootFrame.CanGoBack)
{
rootFrame.GoBack();
return true;
}
return false;
}
// Perform forward navigation if possible.
private bool TryGoForward()
{
Frame rootFrame = Window.Current.Content as Frame;
if (rootFrame.CanGoForward)
{
rootFrame.GoForward();
return true;
}
return false;
}
// Invoked on every keystroke, including system keys such as Alt key combinations.
// Used to detect keyboard navigation between pages even when the page itself
// doesn't have focus.
private void CoreDispatcher_AcceleratorKeyActivated(CoreDispatcher sender, AcceleratorKeyEventArgs e)
{
// When Alt+Left are pressed navigate back.
// When Alt+Right are pressed navigate forward.
if (e.EventType == CoreAcceleratorKeyEventType.SystemKeyDown
&& (e.VirtualKey == VirtualKey.Left || e.VirtualKey == VirtualKey.Right)
&& e.KeyStatus.IsMenuKeyDown == true
&& !e.Handled)
{
if (e.VirtualKey == VirtualKey.Left)
{
e.Handled = TryGoBack();
}
else if (e.VirtualKey == VirtualKey.Right)
{
e.Handled = TryGoForward();
}
}
}
// Handle system back requests.
private void System_BackRequested(object sender, BackRequestedEventArgs e)
{
if (!e.Handled)
{
e.Handled = TryGoBack();
}
}
// Handle mouse back button.
private void CoreWindow_PointerPressed(CoreWindow sender, PointerEventArgs e)
{
// For this event, e.Handled arrives as 'true'.
if (e.CurrentPoint.Properties.IsXButton1Pressed)
{
e.Handled = !TryGoBack();
}
else if (e.CurrentPoint.Properties.IsXButton2Pressed)
{
e.Handled = !TryGoForward();
}
}
// App.cpp
void App::OnLaunched(LaunchActivatedEventArgs const& e)
{
// ...
// Do not repeat app initialization when the Window already has content,
// just ensure that the window is active
if (rootFrame == nullptr)
{
// ...
// rootFrame.NavigationFailed({ this, &App::OnNavigationFailed });
// Add support for accelerator keys.
// Listen to the window directly so the app responds
// to accelerator keys regardless of which element has focus.
Window::Current().CoreWindow().Dispatcher().
AcceleratorKeyActivated({ this, &App::CoreDispatcher_AcceleratorKeyActivated });
// Add support for system back requests.
SystemNavigationManager::GetForCurrentView().
BackRequested({ this, &App::System_BackRequested });
// Add support for mouse navigation buttons.
Window::Current().CoreWindow().
PointerPressed({ this, &App::CoreWindow_PointerPressed });
// ...
}
}
// App.h
#include "winrt/Windows.UI.Core.h"
#include "winrt/Windows.System.h"
#include "winrt/Windows.UI.Input.h"
#include "winrt/Windows.UI.Xaml.Input.h"
using namespace winrt;
using namespace Windows::Foundation;
using namespace Windows::UI::Core;
using namespace Windows::UI::Input;
using namespace Windows::UI::Xaml;
using namespace Windows::UI::Xaml::Controls;
struct App : AppT<App>
{
App();
// ...
// Perform back navigation if possible.
static bool TryGoBack()
{
Frame rootFrame{ nullptr };
auto content = Window::Current().Content();
if (content)
{
rootFrame = content.try_as<Frame>();
if (rootFrame.CanGoBack())
{
rootFrame.GoBack();
return true;
}
}
return false;
}
private:
// Perform forward navigation if possible.
bool TryGoForward()
{
Frame rootFrame{ nullptr };
auto content = Window::Current().Content();
if (content)
{
rootFrame = content.try_as<Frame>();
if (rootFrame.CanGoForward())
{
rootFrame.GoForward();
return true;
}
}
return false;
}
// Invoked on every keystroke, including system keys such as Alt key combinations.
// Used to detect keyboard navigation between pages even when the page itself
// doesn't have focus.
void CoreDispatcher_AcceleratorKeyActivated(CoreDispatcher const& /* sender */, AcceleratorKeyEventArgs const& e)
{
// When Alt+Left are pressed navigate back.
// When Alt+Right are pressed navigate forward.
if (e.EventType() == CoreAcceleratorKeyEventType::SystemKeyDown
&& (e.VirtualKey() == Windows::System::VirtualKey::Left || e.VirtualKey() == Windows::System::VirtualKey::Right)
&& e.KeyStatus().IsMenuKeyDown
&& !e.Handled())
{
if (e.VirtualKey() == Windows::System::VirtualKey::Left)
{
e.Handled(TryGoBack());
}
else if (e.VirtualKey() == Windows::System::VirtualKey::Right)
{
e.Handled(TryGoForward());
}
}
}
// Handle system back requests.
void System_BackRequested(IInspectable const& /* sender */, BackRequestedEventArgs const& e)
{
if (!e.Handled())
{
e.Handled(TryGoBack());
}
}
// Handle mouse forward and back buttons.
void CoreWindow_PointerPressed(CoreWindow const& /* sender */, PointerEventArgs const& e)
{
// For this event, e.Handled arrives as 'true'.
if (e.CurrentPoint().Properties().IsXButton1Pressed())
{
e.Handled(!TryGoBack());
}
else if (e.CurrentPoint().Properties().IsXButton2Pressed())
{
e.Handled(!TryGoForward());
}
}
};
Продолжение
Когда пользователь переключается на другое приложение и возвращается в приложение, рекомендуется вернуться на последнюю страницу в журнале навигации.