Implementieren der Navigation zwischen zwei SeitenImplement navigation between two pages

Hier erfährst du, wie du einen Frame und Seiten verwendest, um in deiner App eine einfache Peer-zu-Peer-Navigation zu ermöglichen.Learn how to use a frame and pages to enable basic peer-to-peer navigation in your app.

Wichtige APIs: Klasse Windows.UI.Xaml.Controls.Frame, Klasse Windows.UI.Xaml.Controls.Page, Namespace Windows.UI.Xaml.NavigationImportant APIs: Windows.UI.Xaml.Controls.Frame class, Windows.UI.Xaml.Controls.Page class, Windows.UI.Xaml.Navigation namespace

Peer-to-Peer-Navigation

1. Erstellen einer leeren App1. Create a blank app

  1. Wähle im Menü von Microsoft Visual Studio Datei > Neues Projekt aus.On the Microsoft Visual Studio menu, choose File > New Project.
  2. Wähle im linken Bereich des Dialogfelds Neues Projekt den Knoten Visual C# > Windows > Universell oder Visual C++ > Windows > Universell aus.In the left pane of the New Project dialog box, choose the Visual C# > Windows > Universal or the Visual C++ > Windows > Universal node.
  3. Wählen Sie im mittleren Bereich die Option Leere App aus.In the center pane, choose Blank App.
  4. Geben Sie in das Feld Name den Wert NavApp1 ein, und klicken Sie anschließend auf OK.In the Name box, enter NavApp1, and then choose the OK button. Die Projektmappe wird erstellt, und die Projektdateien werden im Projektmappen-Explorer angezeigt.The solution is created, and the project files appear in Solution Explorer.
  5. Klicken Sie zum Ausführen des Programms im Menü auf Debuggen > Debugging starten, oder drücken Sie F5.To run the program, choose Debug > Start Debugging from the menu, or press F5. Es wird eine leere Seite angezeigt.A blank page is displayed.
  6. Um das Debuggen zu beenden und zu Visual Studio zurückzukehren, kannst du entweder die App beenden oder im Menü auf Debuggen beenden klicken.To stop debugging and return to Visual Studio, exit the app, or click Stop Debugging from the menu.

2. Hinzufügen von Standardseiten2. Add basic pages

Füge als Nächstes deinem Projekt zwei Seiten hinzu.Next, add two pages to the project.

  1. Klicken Sie im Projektmappen-Explorer mit der rechten Maustaste auf den Projektknoten BlankApp, um das Kontextmenü zu öffnen.In Solution Explorer, right-click the BlankApp project node to open the shortcut menu.
  2. Wählen Sie im Kontextmenü Hinzufügen > Neues Element aus.Choose Add > New Item from the shortcut menu.
  3. Wählen Sie im Dialogfeld Neues Element hinzufügen im mittleren Bereich die Option Leere Seite aus.In the Add New Item dialog box, choose Blank Page in the middle pane.
  4. Geben Sie in das Feld Name den Wert Page1 (oder Page2) ein, und wählen Sie anschließend Hinzufügen.In the Name box, enter Page1 (or Page2) and press the Add button.
  5. Wiederhole die Schritte 1 bis 4, um die zweite Seite hinzuzufügen.Repeat steps 1-4 to add the second page.

Die Dateiliste des Projekts „NavApp1“ sollte nun folgende Dateien enthalten:Now, these files should be listed as part of your NavApp1 project.

C#C# C++C++
  • Page1.xamlPage1.xaml
  • Page1.xaml.csPage1.xaml.cs
  • Page2.xamlPage2.xaml
  • Page2.xaml.csPage2.xaml.cs
  • Page1.xamlPage1.xaml
  • Page1.xaml.cppPage1.xaml.cpp
  • Page1.xaml.hPage1.xaml.h
  • Page2.xamlPage2.xaml
  • Page2.xaml.cppPage2.xaml.cpp
  • Page2.xaml.hPage2.xaml.h

Füge in „Page1.xaml“ den folgenden Inhalt hinzu:In Page1.xaml, add the following content:

  • Ein TextBlock-Element mit der Bezeichnung pageTitle als untergeordnetes Element des Grid-Stammelements.A TextBlock element named pageTitle as a child element of the root Grid. Ändern Sie die Text-Eigenschaft in Page 1.Change the Text property to Page 1.
<TextBlock x:Name="pageTitle" Text="Page 1" />
<HyperlinkButton Content="Click to go to page 2"
                 Click="HyperlinkButton_Click"
                 HorizontalAlignment="Center"/>

Füge in der CodeBehind-Datei „Page1.xaml“ den folgenden Code hinzu, um das Click-Ereignis des HyperlinkButton-Elements zu behandeln, das du für die Navigation zu „Page2.xaml“ hinzugefügt hast.In the Page1.xaml code-behind file, add the following code to handle the Click event of the HyperlinkButton you added to navigate to Page2.xaml.

private void HyperlinkButton_Click(object sender, RoutedEventArgs e)
{
    this.Frame.Navigate(typeof(Page2));
}
void Page1::HyperlinkButton_Click(Windows::Foundation::IInspectable const& sender, Windows::UI::Xaml::RoutedEventArgs const& args)
{
    Frame().Navigate(winrt::xaml_typename<NavApp1::Page2>());
}
void Page1::HyperlinkButton_Click(Platform::Object^ sender, RoutedEventArgs^ e)
{
    this->Frame->Navigate(Windows::UI::Xaml::Interop::TypeName(Page2::typeid));
}

Füge in „Page2.xaml“ den folgenden Inhalt hinzu:In Page2.xaml, add the following content:

  • Ein TextBlock-Element mit der Bezeichnung pageTitle als untergeordnetes Element des Grid-Stammelements.A TextBlock element named pageTitle as a child element of the root Grid. Ändern Sie den Wert der Text-Eigenschaft in Page 2:Change the value of the Text property to Page 2.
<TextBlock x:Name="pageTitle" Text="Page 2" />
<HyperlinkButton Content="Click to go to page 1" 
                 Click="HyperlinkButton_Click"
                 HorizontalAlignment="Center"/>

Füge in der CodeBehind-Datei „Page2.xaml“ den folgenden Code hinzu, um das Click-Ereignis des HyperlinkButton-Elements für die Navigation zu „Page1.xaml“ zu behandeln.In the Page2.xaml code-behind file, add the following code to handle the Click event of the HyperlinkButton to navigate to Page1.xaml.

private void HyperlinkButton_Click(object sender, RoutedEventArgs e)
{
    this.Frame.Navigate(typeof(Page1));
}
void Page2::HyperlinkButton_Click(Windows::Foundation::IInspectable const& sender, Windows::UI::Xaml::RoutedEventArgs const& args)
{
    Frame().Navigate(winrt::xaml_typename<NavApp1::Page1>());
}
void Page2::HyperlinkButton_Click(Platform::Object^ sender, RoutedEventArgs^ e)
{
    this->Frame->Navigate(Windows::UI::Xaml::Interop::TypeName(Page1::typeid));
}

Hinweis

Im Fall von C++-Projekten müssen Sie in der Headerdatei jeder Seite, die auf eine andere Seite verweist, eine #include-Anweisung hinzufügen.For C++ projects, you must add a #include directive in the header file of each page that references another page. Für das hier gezeigte Beispiel für die seitenübergreifende Navigation enthält die Datei „page1.xaml.h“ #include "Page2.xaml.h", und die Datei „page2.xaml.h“ wiederum enthält #include "Page1.xaml.h".For the inter-page navigation example presented here, page1.xaml.h file contains #include "Page2.xaml.h", in turn, page2.xaml.h contains #include "Page1.xaml.h".

Nachdem wir die Seiten vorbereitet haben, müssen wir dafür sorgen, dass beim Start der App „Page1.xaml“ angezeigt wird.Now that we've prepared the pages, we need to make Page1.xaml display when the app starts.

Öffne die CodeBehind-Datei „App.xaml“, und ändere den OnLaunched-Handler.Open the App.xaml code-behind file and change the OnLaunched handler.

Hier geben wir Page1 im Aufruf von Frame.Navigate anstelle von MainPage an.Here, we specify Page1 in the call to Frame.Navigate instead of MainPage.

protected override void OnLaunched(LaunchActivatedEventArgs e)
{
    Frame rootFrame = Window.Current.Content as Frame;
 
    // Do not repeat app initialization when the Window already has content,
    // just ensure that the window is active
    if (rootFrame == null)
    {
        // Create a Frame to act as the navigation context and navigate to the first page
        rootFrame = new Frame();
        rootFrame.NavigationFailed += OnNavigationFailed;
 
        if (e.PreviousExecutionState == ApplicationExecutionState.Terminated)
        {
            //TODO: Load state from previously suspended application
        }
 
        // Place the frame in the current Window
        Window.Current.Content = rootFrame;
    }
 
    if (rootFrame.Content == null)
    {
        // When the navigation stack isn't restored navigate to the first page,
        // configuring the new page by passing required information as a navigation
        // parameter
        rootFrame.Navigate(typeof(Page1), e.Arguments);
    }
    // Ensure the current window is active
    Window.Current.Activate();
}
void App::OnLaunched(LaunchActivatedEventArgs const& e)
{
    Frame rootFrame{ nullptr };
    auto content = Window::Current().Content();
    if (content)
    {
        rootFrame = content.try_as<Frame>();
    }

    // Do not repeat app initialization when the Window already has content,
    // just ensure that the window is active
    if (rootFrame == nullptr)
    {
        // Create a Frame to act as the navigation context and associate it with
        // a SuspensionManager key
        rootFrame = Frame();

        rootFrame.NavigationFailed({ this, &App::OnNavigationFailed });

        if (e.PreviousExecutionState() == ApplicationExecutionState::Terminated)
        {
            // Restore the saved session state only when appropriate, scheduling the
            // final launch steps after the restore is complete
        }

        if (e.PrelaunchActivated() == false)
        {
            if (rootFrame.Content() == nullptr)
            {
                // When the navigation stack isn't restored navigate to the first page,
                // configuring the new page by passing required information as a navigation
                // parameter
                rootFrame.Navigate(xaml_typename<NavApp1::Page1>(), box_value(e.Arguments()));
            }
            // Place the frame in the current Window
            Window::Current().Content(rootFrame);
            // Ensure the current window is active
            Window::Current().Activate();
        }
    }
    else
    {
        if (e.PrelaunchActivated() == false)
        {
            if (rootFrame.Content() == nullptr)
            {
                // When the navigation stack isn't restored navigate to the first page,
                // configuring the new page by passing required information as a navigation
                // parameter
                rootFrame.Navigate(xaml_typename<NavApp1::Page1>(), box_value(e.Arguments()));
            }
            // Ensure the current window is active
            Window::Current().Activate();
        }
    }
}
void App::OnLaunched(Windows::ApplicationModel::Activation::LaunchActivatedEventArgs^ e)
{
    auto rootFrame = dynamic_cast<Frame^>(Window::Current->Content);

    // Do not repeat app initialization when the Window already has content,
    // just ensure that the window is active
    if (rootFrame == nullptr)
    {
        // Create a Frame to act as the navigation context and associate it with
        // a SuspensionManager key
        rootFrame = ref new Frame();

        rootFrame->NavigationFailed += 
            ref new Windows::UI::Xaml::Navigation::NavigationFailedEventHandler(
                this, &App::OnNavigationFailed);

        if (e->PreviousExecutionState == ApplicationExecutionState::Terminated)
        {
            // TODO: Load state from previously suspended application
        }
        
        // Place the frame in the current Window
        Window::Current->Content = rootFrame;
    }

    if (rootFrame->Content == nullptr)
    {
        // When the navigation stack isn't restored navigate to the first page,
        // configuring the new page by passing required information as a navigation
        // parameter
        rootFrame->Navigate(Windows::UI::Xaml::Interop::TypeName(Page1::typeid), e->Arguments);
    }

    // Ensure the current window is active
    Window::Current->Activate();
}

Hinweis

In diesem Beispielcode wird der Rückgabewert von Navigate verwendet, um eine App-Ausnahme auszulösen, wenn die Navigation zum anfänglichen Fensterrahmen der App einen Fehler verursacht.The code here uses the return value of Navigate to throw an app exception if the navigation to the app's initial window frame fails. Wenn Navigate den Wert true zurückgibt, findet die Navigation statt.When Navigate returns true, the navigation happens.

Erstellen Sie nun die App, und führen Sie sie aus.Now, build and run the app. Klicken Sie auf den Link „Click to go to page 2“.Click the link that says "Click to go to page 2". Die zweite Seite mit der Bezeichnung „Seite 2“ wird geladen und im Frame angezeigt.The second page that says "Page 2" at the top should be loaded and displayed in the frame.

Informationen zur Frame- und Page-KlasseAbout the Frame and Page classes

Bevor wir der App weitere Funktionen hinzufügen, sehen wir uns zunächst an, wie die hinzugefügten Seiten die Navigation in unserer App ermöglichen.Before we add more functionality to our app, let's look at how the pages we added provide navigation within our app.

Zuerst wird in der CodeBehind-Datei „App.xaml“ in der Methode App.OnLaunched eine Frame-Klasse namens rootFrame für die App erstellt.First, a Frame called rootFrame is created for the app in the App.OnLaunched method in the App.xaml code-behind file. Die Frame-Klasse unterstützt verschiedene Navigationsmethoden wie Navigate, GoBackund GoForward sowie Eigenschaften wie BackStack, ForwardStack und BackStackDepth.The Frame class supports various navigation methods such as Navigate, GoBack, and GoForward, and properties such as BackStack, ForwardStack, and BackStackDepth.   Die Navigate-Methode wird zum Anzeigen von Inhalt im Frame verwendet.The Navigate method is used to display content in this Frame. Standardmäßig lädt diese Methode „MainPage.xaml“.By default, this method loads MainPage.xaml. In unserem Beispiel wird Page1 an die Methode Navigate übergeben, sodass durch die Methode Page1 im Frame geladen wird.In our example, Page1 is passed to the Navigate method, so the method loads Page1 in the Frame.

Page1 ist eine Unterklasse der Page-Klasse.Page1 is a subclass of the Page class. Die Page-Klasse verfügt über eine schreibgeschützte Frame-Eigenschaft, die den Frame abruft, der Page enthält.The Page class has a read-only Frame property that gets the Frame containing the Page. Wenn der Click-Ereignishandler von HyperlinkButtonthis.Frame.Navigate(typeof(Page2)) in Page1 aufruft, zeigt das Frame-Element den Inhalt von „Page2.xaml“ an.When the Click event handler of the HyperlinkButton in Page1 calls this.Frame.Navigate(typeof(Page2)), the Frame displays the content of Page2.xaml.

Und wenn eine Seite in den Frame geladen wird, wird sie als PageStackEntry zu BackStack oder ForwardStack des Frame-Elements hinzugefügt, um die Verwendung von Verlauf und Rückwärtsnavigation zu ermöglichen.Finally, whenever a page is loaded into the frame, that page is added as a PageStackEntry to the BackStack or ForwardStack of the Frame, allowing for history and backwards navigation.

3. Übergeben von Informationen zwischen Seiten3. Pass information between pages

Unsere App navigiert zwischen zwei Seiten, sie bietet jedoch noch keine interessanten Funktionen.Our app navigates between two pages, but it really doesn't do anything interesting yet. Bei vielen Apps mit mehreren Seiten müssen die Seiten Informationen freigeben.Often, when an app has multiple pages, the pages need to share information. Übergeben wir also einige Informationen der ersten Seite an die zweite Seite.Let's pass some information from the first page to the second page.

Ersetze in „Page1.xaml“ das zuvor hinzugefügte HyperlinkButton-Element durch die folgende StackPanel-Klasse.In Page1.xaml, replace the HyperlinkButton you added earlier with the following StackPanel.

Hier fügen wir eine TextBlock-Bezeichnung und ein TextBox-Element (name) zum Eingeben einer Textzeichenfolge hinzu.Here, we add a TextBlock label and a TextBox name for entering a text string.

<StackPanel>
    <TextBlock HorizontalAlignment="Center" Text="Enter your name"/>
    <TextBox HorizontalAlignment="Center" Width="200" Name="name"/>
    <HyperlinkButton Content="Click to go to page 2" 
                     Click="HyperlinkButton_Click"
                     HorizontalAlignment="Center"/>
</StackPanel>

Füge der Navigate-Methode in der CodeBehind-Datei „Page1.xaml“ im HyperlinkButton_Click-Ereignishandler einen Parameter hinzu, der auf die Text-Eigenschaft von name TextBox verweist.In the HyperlinkButton_Click event handler of the Page1.xaml code-behind file, add a parameter referencing the Text property of the name TextBox to the Navigate method.

private void HyperlinkButton_Click(object sender, RoutedEventArgs e)
{
    this.Frame.Navigate(typeof(Page2), name.Text);
}
void Page1::HyperlinkButton_Click(Windows::Foundation::IInspectable const& sender, Windows::UI::Xaml::RoutedEventArgs const& args)
{
    Frame().Navigate(winrt::xaml_typename<NavApp1::Page2>(), winrt::box_value(name().Text()));
}
void Page1::HyperlinkButton_Click(Platform::Object^ sender, RoutedEventArgs^ e)
{
    this->Frame->Navigate(Windows::UI::Xaml::Interop::TypeName(Page2::typeid), name->Text);
}

Ersetze in „Page2.xaml“ das zuvor hinzugefügte HyperlinkButton-Element durch die folgende StackPanel-Klasse.In Page2.xaml, replace the HyperlinkButton you added earlier with the following StackPanel.

Hier fügen wir einen Textblock (TextBlock) zum Anzeigen der von Seite 1 übergebenen Textzeichenfolge hinzu.Here, we add a TextBlock for displaying the text string passed from Page1.

<StackPanel>
    <TextBlock HorizontalAlignment="Center" Name="greeting"/>
    <HyperlinkButton Content="Click to go to page 1" 
                     Click="HyperlinkButton_Click"
                     HorizontalAlignment="Center"/>
</StackPanel>

Füge der CodeBehind-Datei „Page2.xaml“ Folgendes hinzu, um die OnNavigatedTo-Methode zu überschreiben:In the Page2.xaml code-behind file, add the following to override the OnNavigatedTo method:

protected override void OnNavigatedTo(NavigationEventArgs e)
{
    if (e.Parameter is string && !string.IsNullOrWhiteSpace((string)e.Parameter))
    {
        greeting.Text = $"Hi, {e.Parameter.ToString()}";
    }
    else
    {
        greeting.Text = "Hi!";
    }
    base.OnNavigatedTo(e);
}
void Page2::OnNavigatedTo(Windows::UI::Xaml::Navigation::NavigationEventArgs const& e)
{
    auto propertyValue{ e.Parameter().as<Windows::Foundation::IPropertyValue>() };
    if (propertyValue.Type() == Windows::Foundation::PropertyType::String)
    {
        greeting().Text(L"Hi, " + winrt::unbox_value<winrt::hstring>(e.Parameter()));
    }
    else
    {
        greeting().Text(L"Hi!");
    }
    __super::OnNavigatedTo(e);
}
void Page2::OnNavigatedTo(NavigationEventArgs^ e)
{
    if (dynamic_cast<Platform::String^>(e->Parameter) != nullptr)
    {
        greeting->Text = "Hi, " + e->Parameter->ToString();
    }
    else
    {
        greeting->Text = "Hi!";
    }
    ::Windows::UI::Xaml::Controls::Page::OnNavigatedTo(e);
}

Führen Sie die App aus, geben Sie Ihren Namen in das Textfeld ein, und klicken Sie auf den Link Click to go to page 2.Run the app, type your name in the text box, and then click the link that says Click to go to page 2.

Wenn this.Frame.Navigate(typeof(Page2), name.Text) durch das Click-Ereignis des HyperlinkButton-Elements in Page1 aufgerufen wird, wird die name.Text-Eigenschaft an Page2 übergeben, und der Wert aus den Ereignisdaten wird für die auf der Seite angezeigte Nachricht verwendet.When the Click event of the HyperlinkButton in Page1 calls this.Frame.Navigate(typeof(Page2), name.Text), the name.Text property is passed to Page2, and the value from the event data is used for the message displayed on the page.

4. Zwischenspeichern einer Seite4. Cache a page

Seiteninhalt und -zustand werden standardmäßig nicht zwischengespeichert. Wenn du also Informationen zwischenspeichern möchtest, musst du dies auf jeder Seite deiner App aktivieren.Page content and state is not cached by default, so if you'd like to cache information, you must enable it in each page of your app.

In unserem einfachen Peer-zu-Peer-Beispiel gibt es keine Zurück-Schaltfläche. (Informationen zur Rückwärtsnavigation findest du hier.) Wenn jedoch eine Zurück-Schaltfläche vorhanden wäre und du auf Page2 darauf klicken würdest, hätte dies zur Folge, dass das TextBox-Element (und alle anderen Felder) auf Page1 wieder auf den Standardzustand zurückgesetzt werden.In our basic peer-to-peer example, there is no back button (we demonstrate back navigation in backwards navigation), but if you did click a back button on Page2, the TextBox (and any other field) on Page1 would be set to its default state. Eine Möglichkeit zur Umgehung dieses Problems ist die Verwendung der NavigationCacheMode-Eigenschaft, um anzugeben, dass eine Seite zum Seitencache des Frames hinzugefügt werden soll.One way to work around this is to use the NavigationCacheMode property to specify that a page be added to the frame's page cache.

Im Konstruktor von Page1 kannst du NavigationCacheMode auf Enabled festlegen, um alle Inhalte und Zustandswerte für die Seite beizubehalten, bis der Seitencache für den Frame überschritten wird.In the constructor of Page1, you can set NavigationCacheMode to Enabled to retains all content and state values for the page until the page cache for the frame is exceeded. Lege NavigationCacheMode auf Required fest, wenn du CacheSize-Limits ignorieren möchtest. (Diese Limits geben die Anzahl von Seiten an, die im Navigationsverlauf für den Frame zwischengespeichert werden können.)Set NavigationCacheMode to Required if you want to ignore CacheSize limits, which specify the number of pages in the navigation history that can be cached for the frame. Die Beschränkung der Cachegröße kann allerdings je nach Arbeitsspeichergröße eines Geräts äußerst wichtig sein.However, keep in mind that cache size limits might be crucial, depending on the memory limits of a device.

public Page1()
{
    this.InitializeComponent();
    this.NavigationCacheMode = Windows.UI.Xaml.Navigation.NavigationCacheMode.Enabled;
}
Page1::Page1()
{
    InitializeComponent();
    NavigationCacheMode(Windows::UI::Xaml::Navigation::NavigationCacheMode::Enabled);
}
Page1::Page1()
{
    this->InitializeComponent();
    this->NavigationCacheMode = Windows::UI::Xaml::Navigation::NavigationCacheMode::Enabled;
}