次の方法で共有


UWP アプリの戻るナビゲーション

重要な API: Windows.UI.Xaml.Controls.Frame クラス、 Windows.UI.Xaml.Controls.Page クラス、 Windows.UI.Xaml.Navigation 名前空間、 OnNavigatedTo

アプリに後方ナビゲーションを実装するには、アプリの UI の左上隅に戻るボタンを配置します。 ユーザーは、戻るボタンがアプリのナビゲーション履歴の前の場所に移動することを想定しています。 既定では、 Frame コントロールはナビゲーション アクションを BackStack と ForwardStack に記録 します。 ただし、ナビゲーション履歴に追加するナビゲーション アクションを変更できます。

複数のページを持つほとんどのアプリでは、 NavigationView コントロールを使用してアプリのナビゲーション フレームワークを提供することをお勧めします。 これは、さまざまな画面サイズに適応し、上部のナビゲーション スタイルと左側のナビゲーション スタイルの両方をサポートしています。 アプリで NavigationView コントロールを使用している場合は、 NavigationView の組み込みの戻るボタンを使用できます。

この記事のガイドラインと例は、 NavigationView コントロールを使用せずにナビゲーションを実装する場合に使用する必要があります。 NavigationViewを使用する場合、この情報は有用な背景知識を提供しますが、NavigationView に関する記事の具体的なガイダンスと例を使用する必要があります

[戻る] ボタン

戻るボタンを作成するには、 スタイルの NavigationBackButtonNormalStyle コントロールを使用し、アプリの UI の左上隅にボタンを配置します (詳細については、以下の XAML コード例を参照してください)。

アプリの 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 がある場合は、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>

アプリ内を移動する UI 要素を最小限に抑えるには、バックスタック (IsEnabled="{x:Bind Frame.CanGoBack, Mode=OneWay}") に何も存在しないときに無効な [戻る] ボタンを表示します。 ただし、アプリにバックスタックがない場合は、戻るボタンをまったく表示する必要はありません。

戻るボタンの状態

さまざまなデバイスと入力に合わせて最適化する

この後方ナビゲーション設計ガイダンスはすべてのデバイスに適用できますが、さまざまなフォーム ファクターや入力方法に合わせて最適化すると、ユーザーのメリットが得られます。 戻るナビゲーションの最も一般的な入力をサポートするには、(戻るボタンクリックに加えて) 次のイベントを処理することをお勧めします。

出来事 インプット
CoreDispatcher.AcceleratorKeyActivated Alt + 左矢印、
バーチャルキー.戻る
SystemNavigationManager.BackRequested Windows + Backspace、
ゲームパッド B ボタン、
タブレット モードの戻るボタン、
ハードウェアの戻るボタン
CoreWindow.PointerPressed VirtualKey.XButton1
(一部のマウスで見つかった [戻る] ボタンなど)。

コード例

このセクションでは、さまざまな入力を使用して戻るナビゲーションを処理する方法について説明します。

戻るボタンと戻るナビゲーション

少なくとも、イベント 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キー+ バックスペースキーショートカット、またはタブレットモードのシステム戻るボタンです。使用できる正確なオプションは、デバイスによって異なります。

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 はタイトル バー内にシステムの戻るボタンをレンダリングします。 ([戻る] ボタンの外観とユーザーの操作は、以前のビルドから変更されません)。

タイトルバーの [戻る] ボタン

マウス ナビゲーション ボタンを処理する

一部のマウスには、前方ナビゲーションと戻るナビゲーション用のハードウェア ナビゲーション ボタンが用意されています。 これらのマウスボタンは、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());
        }
    }
};

再開

ユーザーが別のアプリに切り替えてアプリに戻ったら、ナビゲーション履歴の最後のページに戻うことをお勧めします。