Windows 앱을 위한 탐색 기록 및 뒤로 탐색

중요 APIs: BackRequested 이벤트, SystemNavigationManager 클래스, OnNavigatedTo

Windows 앱은 앱 내에서 그리고 디바이스에 따라 앱 간에 사용자의 탐색 기록을 탐색할 수 있도록 일관적인 뒤로 탐색 시스템을 제공합니다.

앱에 뒤로 탐색 기능을 구현하려면 앱 UI 왼쪽 위 모서리에 뒤로 단추를 배치합니다. 사용자는 뒤로 가기 버튼을 통해 앱의 탐색 기록에서 이전 위치로 이동할 것을 예상합니다. 탐색 기록에 추가할 탐색 동작과 뒤로 단추 누르기에 응답하는 방식은 사용자가 결정해야 합니다.

여러 페이지가 있는 대부분의 앱에서는 NavigationView 컨트롤을 사용하여 앱에 대한 탐색 프레임워크를 제공하는 것이 좋습니다. 이 컨트롤은 다양한 화면 크기에 맞게 조정되고 ‘위쪽’ 및 ‘왼쪽’ 탐색 스타일을 둘 다 지원합니다. 앱에서 NavigationView 컨트롤을 사용하는 경우 NavigationView의 기본 뒤로 단추를 사용할 수 있습니다.

참고 항목

NavigationView 컨트롤을 사용하지 않고 탐색을 구현하는 경우 이 문서의 지침과 예제를 사용해야 합니다. NavigationView를 사용하는 경우 이 정보는 유용한 배경 지식을 제공하지만, NavigationView 문서에 제공된 구체적인 지침과 예제를 사용해야 합니다.

뒤로 버튼

뒤로 단추를 만들려면 NavigationBackButtonNormalStyle 스타일의 단추 컨트롤을 사용하고, 앱 UI의 왼쪽 위 모서리에 단추를 배치합니다(자세한 내용은 아래의 XAML 코드 예제 참조).

Back button in the top left of the app's UI

<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가 있다면 높이가 44epx인 단추 컨트롤과 48epx인 AppBarButton이 매끄럽게 정렬되지 않을 것입니다. 이런 문제를 방지하려면 단추 컨트롤 위쪽을 48epx 범위 내로 맞춥니다.

Back button on top command bar

<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>

UI 요소가 앱 내부를 돌아다니는 일을 최소화하려면 백스택에 아무 것도 없을 때 비활성화된 뒤로 단추를 표시하세요(IsEnabled="{x:Bind Frame.CanGoBack, Mode=OneWay}"). 하지만 앱에 백스택이 없는 것이 분명한 경우에는 뒤로 단추를 표시할 필요가 없습니다.

Back button states

다양한 디바이스 및 입력에 맞게 최적화

이 역방향 탐색 디자인 지침은 모든 디바이스에 적용되지만, 다양한 폼 팩터 및 입력 방법을 최적화할 때 사용자에게 도움이 됩니다.

UI를 최적화하는 방법은 다음과 같습니다.

  • 데스크톱/허브: 앱 UI 왼쪽 윗 모서리에 인앱 버튼을 구현합니다.
  • 태블릿 모드: 태블릿에 하드웨어 또는 소프트웨어 뒤로 가기 버튼이 있을 수 있지만, 명확하려면 인앱 뒤로 가기 버튼을 구현하는 것이 좋습니다.
  • Xbox/TV: 뒤로 가기 버튼을 구현하지 않습니다. 추가하면 UI가 불필요하게 복잡해집니다. 대신 게임패드의 B 버튼을 사용하여 뒤로 탐색합니다.

앱이 Xbox에서 실행되는 경우 단추 표시 여부를 전환하는 Xbox의 사용자 지정 시각적 트리거를 만듭니다. NavigationView 컨트롤을 사용할 경우 앱이 Xbox에서 실행되면 이 컨트롤이 자동으로 뒤로 단추를 토글합니다.

뒤로 탐색을 위한 가장 일반적인 입력을 지원하려면 뒤로 단추 클릭 외에도 다음 이벤트를 처리하는 것이 좋습니다.

이벤트 입력
CoreDispatcher.AcceleratorKeyActivated Alt+왼쪽 화살표,
VirtualKey.GoBack
SystemNavigationManager.BackRequested Windows + 백스페이스 키,
게임 패드 B 단추,
태블릿 모드 뒤로 단추,
하드웨어 뒤로 버튼
CoreWindow.PointerPressed VirtualKey.XButton1
(예: 일부 마우스의 뒤로 단추)

코드 예제

이 섹션에서는 다양한 입력을 사용하여 뒤로 탐색을 처리하는 방법을 보여줍니다.

뒤로 단추 및 뒤로 탐색

최소한 뒤로 단추 Click 이벤트를 처리하고 뒤로 탐색을 수행하는 코드를 제공해야 합니다. 또한 백스택이 비어 있는 경우 뒤로 단추를 사용하지 않도록 설정해야 합니다.

다음 코드 예제에서는 뒤로 단추를 사용하여 뒤로 탐색 동작을 구현하는 방법을 보여줍니다. 이 코드는 단추 클릭 이벤트에 응답하여 탐색합니다. 뒤로 단추는 새 페이지를 탐색할 때 호출되는 OnNavigatedTo 메서드에서 사용하거나 사용하지 않도록 설정됩니다.

이 코드는 MainPage에 대한 것이지만, 뒤로 탐색을 지원하는 각 페이지에 이 코드를 추가합니다. 중복을 방지하려면 App.xaml.* 코드 숨김 페이지의 App 클래스에 탐색 관련 코드를 넣으면 됩니다.

<!-- 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
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 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)
    {
        // ...
        // 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 키 + 백스페이스 키 바로 가기 또는 태블릿 모드의 시스템 뒤로 단추가 있으며, 사용 가능한 정확한 옵션은 디바이스에 따라 다릅니다.

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를 계속 사용하는 경우 시스템 UI는 제목 표시줄 내부에 시스템 뒤로 단추를 렌더링합니다. (뒤로 단추의 모양과 사용자 상호 작용은 이전 빌드와 달라진 것이 없습니다.)

Title bar back button

마우스 탐색 단추 처리

일부 마우스는 앞으로 및 뒤로 탐색을 위한 하드웨어 탐색 단추를 제공합니다. 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());
        }
    }
};

사용자 지정 뒤로 탐색 동작에 대한 지침

고유한 백 스택 탐색을 제공하도록 선택한 경우, 다른 앱과 경험이 일관돼야 합니다. 탐색 작업에 대해 다음 패턴을 따르는 것이 좋습니다.

탐색 작업 탐색 기록에 추가하시겠습니까?
페이지 간, 다른 피어 그룹

이 그림에서 사용자는 앱의 수준 1에서 수준 2로 이동하여 피어 그룹을 교차하므로 탐색이 탐색 기록에 추가됩니다.

Diagram of navigation across peer groups showing the user navigating from group one to group two and the back to group one.

다음 그림에서 사용자는 동일한 수준의 두 피어 그룹 사이를 탐색하고 피어 그룹을 다시 교차하므로 탐색이 탐색 기록에 추가됩니다.

Diagram of navigation across peer groups showing the user navigating from group one to group two then on to group three and back to group two.

페이지 간, 동일한 피어 그룹, 화면 탐색 요소 없음

사용자가 동일한 피어 그룹을 사용하여 한 페이지에서 다른 페이지로 이동합니다. 두 페이지를 직접 탐색하는 화면 탐색 요소(예: NavigationView)는 없습니다.

다음 일러스트레이션에서 사용자는 같은 피어 그룹에 있는 두 페이지 사이를 탐색하며, 탐색 기록에 탐색을 추가해야 합니다.

Navigation within a peer group

페이지 간, 동일한 피어 그룹, 화면 탐색 요소 사용

사용자가 동일한 피어 그룹의 한 페이지에서 다른 페이지로 이동합니다. 두 페이지가 동일한 탐색 요소(예: NavigationView)에 표시됩니다.

유동적

예, 탐색 기록에 추가하지만, 두 가지 주목할 만한 예외가 있습니다. 앱 사용자가 피어 그룹의 페이지 간에 자주 전환할 것으로 예상되는 경우 또는 탐색 계층을 유지하려는 경우에는 탐색 기록에 추가하지 마세요. 이 경우 사용자가 뒤로 탐색을 누르면 현재 피어 그룹으로 이동하기 전에 있던 마지막 페이지로 돌아갑니다.

Navigation across peer groups when a navigation element is present

임시 UI 표시

앱은 대화 상자, 시작 화면 또는 화상 키보드와 같은 팝업 또는 자식 창을 표시하거나, 여러 선택 모드와 같은 특수 모드로 전환됩니다.

문제

사용자가 뒤로 가기 버튼을 누르면, 일시적인 UI를 해제하고(화면 키보드 숨기기, 대화 상자 취소 등) 일시적인 UI를 생성한 페이지로 돌아갑니다.

Showing a transient UI

항목 열거

앱은 목록/세부 정보 목록에서 선택한 항목에 대한 세부 정보와 같이 화면상의 항목에 대한 콘텐츠를 표시합니다.

문제

항목 열거는 피어 그룹 내에서 탐색하는 것과 유사합니다. 사용자가 뒤로 가기를 누르면, 항목 열거형이 있는 현재 페이지의 앞 페이지로 이동합니다.

Iterm enumeration

Resuming

사용자가 다른 앱으로 전환하고 앱으로 돌아오면, 탐색 기록의 마지막 페이지로 돌아가는 것이 좋습니다.