Sdílet prostřednictvím


Zpětná navigace pro aplikace pro UPW

Důležitá rozhraní API: Třída Windows.UI.Xaml.Controls.Frame , Windows.UI.Xaml.Controls.Page třída, Obor názvů Windows.UI.Xaml.Navigation , OnNavigatedTo

Pokud chcete v aplikaci implementovat zpětnou navigaci, umístěte tlačítko Zpět do levého horního rohu uživatelského rozhraní vaší aplikace. Uživatel očekává, že tlačítko Zpět přejde do předchozího umístění v historii navigace aplikace. Ve výchozím nastavení ovládací prvek Rámec zaznamenává navigační akce v backStack a ForwardStack. Můžete ale upravit, které akce navigace se přidají do historie navigace.

Pro většinu aplikací, které mají více stránek, doporučujeme použít ovládací prvek NavigationView k poskytnutí navigačního rozhraní pro vaši aplikaci. Přizpůsobí se různým velikostem obrazovky a podporuje navigační styly jak horní, tak levé. Pokud vaše aplikace používá ovládací prvek NavigationView, můžete použít integrované tlačítko Zpět v rámci NavigationView.

Poznámka:

Pokyny a příklady v tomto článku byste měli použít při implementaci navigace bez použití NavigationView ovládacího prvku. Pokud používáte NavigationView, tyto informace poskytují užitečné základní informace, ale měli byste použít konkrétní instrukce a příklady v článku NavigationView.

Tlačítko Zpět

Pokud chcete vytvořit tlačítko Zpět, použijte ovládací prvek Tlačítko se stylem NavigationBackButtonNormalStyle a umístěte tlačítko do levého horního rohu uživatelského rozhraní vaší aplikace (podrobnosti najdete v níže uvedených příkladech kódu XAML).

Tlačítko Zpět v levém horním rohu uživatelského rozhraní aplikace

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

Pokud má vaše aplikace horní panel CommandBar, umístěte Button ovládací prvek do CommandBar.Content oblasti.

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

Pokud chcete minimalizovat prvky uživatelského rozhraní pohybující se v aplikaci, zobrazte zakázané tlačítko Zpět, pokud v backstacku není nic (IsEnabled="{x:Bind Frame.CanGoBack, Mode=OneWay}"). Pokud ale očekáváte, že vaše aplikace nebude mít backstack, nemusíte vůbec zobrazovat tlačítko Zpět.

stavy tlačítka Zpět

Optimalizace pro různá zařízení a vstupy

Pokyny k návrhu navigace zpět se použijí pro všechna zařízení, ale vaši uživatelé budou mít prospěch, pokud optimalizujete různé faktory formulářů a metody zadávání. Doporučujeme zpracovat následující události (kromě kliknutí zpět) a podporovat nejběžnější vstupy pro navigaci zpět.

Událost Vstup
CoreDispatcher.Zrychlená klávesa aktivována Alt+Šipka vlevo,
VirtualKey.GoBack
SystemNavigationManager.BackRequested Windows + Backspace,
tlačítko B gamepadu
Tlačítko Zpět v režimu tabletu
Hardwarové tlačítko zpět
CoreWindow.PointerPressed VirtualKey.XButton1
(Například tlačítko zpět nalezené na některých myších.)

Příklady kódu

Tato část ukazuje, jak zpracovat navigaci zpět pomocí různých vstupů.

Tlačítko Zpět a navigace zpět

Minimálně musíte zpracovat události tlačítka Zpět Click a zadat programový kód pro provedení zpětné navigace. Tlačítko Zpět byste také měli zakázat, když je backstack prázdný.

Tento ukázkový kód ukazuje, jak implementovat chování zpětné navigace pomocí tlačítka Zpět. Kód odpoví na tlačítko Kliknutím na událost přejdete. Tlačítko Zpět je povoleno nebo zakázáno v metodě OnNavigatedTo, která se vyvolá při navigaci na novou stránku.

Kód se zobrazí pro MainPage, ale tento kód přidáte na každou stránku, která podporuje navigaci zpět. Chcete-li se vyhnout duplikaci, můžete kód související s navigací umístit do třídy App na App.xaml.* kód za stránkou.

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

Kód na pozadí

// 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;
    }
};

Podpora přístupových klíčů

Podpora klávesnice je nedílnou součástí zajištění toho, aby vaše aplikace fungovaly skvěle pro uživatele s různými dovednostmi, schopnostmi a očekáváními. Doporučujeme podporovat klávesy akcelerátoru pro navigaci vpřed i zpět, protože uživatelé, kteří na ně spoléhají, budou očekávat obojí. Další informace najdete v části Interakce s klávesnicí a Klávesové zkratky.

Běžnými klávesami akcelerátoru pro navigaci vpřed a zpět jsou Alt+Šipka vpravo (vpřed) a Alt+Šipka vlevo (zpět). Pokud chcete tyto klíče podporovat pro navigaci, zpracujte událost CoreDispatcher.AcceleratorKeyActivated. Zpracováváte událost, která je přímo v okně (nikoli na prvku na stránce), aby aplikace reagovala na klávesy akcelerátoru bez ohledu na to, který prvek má fokus.

Přidejte kód do App třídy, který podporuje klávesy akcelerátoru a navigaci vpřed, jak je znázorněno zde. (Předpokládá se, že už byl přidán předchozí kód pro podporu tlačítka Zpět.) Všechny App kódy můžete zobrazit společně na konci části Příklady kódu.

// 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());
            }
        }
    }
};

Zpracování požadavků na návrat v systému

Zařízení s Windows poskytují různé způsoby, jak může systém předat zpět navigační požadavek vaší aplikaci. Některé běžné způsoby jsou tlačítko B na gamepadu, klávesa Windows + klávesová zkratka Backspace nebo tlačítko zpět systému v režimu tabletu; přesné dostupné možnosti závisí na zařízení.

Můžete podporovat žádosti o navigaci zpět z hardwarových a softwarových kláves tím, že zaregistrujete posluchače pro událost SystemNavigationManager.BackRequested.

Tady je kód přidaný do třídy App pro podporu zpětných požadavků poskytovaných systémem. (Předpokládá se, že už byl přidán předchozí kód pro podporu tlačítka Zpět.) Všechny App kódy můžete zobrazit společně na konci části Příklady kódu.

// 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());
        }
    }
};

Chování zpětného zálohování systému kvůli zpětné kompatibilitě

Aplikace pro UWP dříve používaly SystemNavigationManager.AppViewBackButtonVisibility k zobrazení nebo skrytí systémového tlačítka zpět pro navigaci zpět. (Toto tlačítko vyvolá událost SystemNavigationManager.BackRequested.) Toto rozhraní API bude nadále podporováno, aby byla zajištěna zpětná kompatibilita, ale již nedoporučujeme používat tlačítko Zpět zviditelněné pomocí AppViewBackButtonVisibility. Místo toho byste měli do aplikace zahrnout vlastní tlačítko zpět, jak je popsáno v tomto článku.

Pokud budete dál používat AppViewBackButtonVisibility, uživatelské rozhraní systému vykreslí tlačítko zpět systému uvnitř záhlaví. (Vzhled a interakce uživatelů pro tlačítko Zpět se nezmění od předchozích buildů.)

tlačítko Zpět na záhlaví

Zpracování navigačních tlačítek myši

Některé myši poskytují hardwarová navigační tlačítka pro navigaci vpřed a zpět. Tato tlačítka myši můžete podporovat zpracováním události CoreWindow.PointerPressed a kontrolou stavu IsXButton1Pressed (zpět) nebo IsXButton2Pressed (vpřed).

Tady je kód přidaný do App třídy, který podporuje navigaci na tlačítku myši. (Předpokládá se, že už byl přidán předchozí kód pro podporu tlačítka Zpět.) Všechny App kódy můžete zobrazit společně na konci části Příklady kódu.

// 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());
        }
    }
};

Veškerý kód přidaný do třídy aplikace

// 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());
        }
    }
};

Pokračování

Když uživatel přepne do jiné aplikace a vrátí se do vaší aplikace, doporučujeme vrátit se na poslední stránku v historii navigace.

  • Základy navigace