Freigeben über


NavigationView

Mit dem NavigationView-Steuerelement wird die Navigation auf oberster Ebene für deine App bereitgestellt. Es ermöglicht die Anpassung an verschiedene Bildschirmgrößen und unterstützt sowohl den Navigationsstil oben als auch links.

Navigation obenNavigation links
Mit „NavigationView“ kann der Navigationsbereich bzw. das Menü entweder oben oder links platziert werden.

Ist dies das richtige Steuerelement?

NavigationView ist ein adaptives Navigationssteuerelement, das für folgende Zwecke gut geeignet ist:

  • Bereitstellen einer einheitlichen Navigationsumgebung für die gesamte App
  • Sparen von Platz auf dem Bildschirm in kleineren Fenstern
  • Organisieren des Zugriffs auf viele Navigationskategorien

Weitere Navigationsmuster findest du unter Navigationsdesigngrundlagen.

UWP und WinUI 2

Wichtig

Die Informationen und Beispiele in diesem Artikel sind für Apps optimiert, die das Windows App SDK und WinUI 3 verwenden, gelten jedoch allgemein für UWP-Apps, die WinUI 2 verwenden. In der UWP-API-Referenz finden Sie plattformspezifische Informationen und Beispiele.

Dieser Abschnitt enthält Informationen, die Sie zum Verwenden des Steuerelements in einer UWP- oder WinUI 2-App benötigen.

Das NavigationView-Steuerelement für UWP-Apps ist Bestandteil von WinUI 2. Weitere Informationen, einschließlich Installationsanweisungen, finden Sie unter WinUI 2. APIs für dieses Steuerelement sind sowohl im Namespace Windows.UI.Xaml.Controls als auch im Namespace Microsoft.UI.Xaml.Controls vorhanden.

Es wird empfohlen, die neueste WinUI 2-Version zu verwenden, um die aktuellsten Formatvorlagen, Vorlagen und Features für alle Steuerelemente abzurufen. Für einige Features von „NavigationView“, z. B. die Navigation oben und die hierarchische Navigation, ist Windows 10, Version 1809 (SDK 17763) oder höher oder WinUI 2 erforderlich.

Zur Verwendung des Codes in diesem Artikel mit WinUI 2 stellen Sie die in Ihrem Projekt enthaltenen Windows-UI-Bibliothek-APIs mithilfe eines Alias in XAML dar (wir verwenden muxc). Weitere Informationen finden Sie unter Erste Schritte mit WinUI 2.

xmlns:muxc="using:Microsoft.UI.Xaml.Controls"

<muxc:NavigationView />

Erstellen einer Navigationsansicht

Die WinUI 3-Katalog-App umfasst interaktive Beispiele für die meisten WinUI 3-Steuerelemente, -Features und -Funktionen. Laden Sie die App aus dem Microsoft Store herunter, oder rufen Sie den Quellcode auf GitHub ab.

Dieses Beispiel zeigt, wie Sie eine einfache Navigationsansicht in XAML erstellen.

<NavigationView>
    <NavigationView.MenuItems>
        <NavigationViewItem Content="Nav Item A"/>
        <NavigationViewItem Content="Nav Item B"/>
        <NavigationViewItem Content="Nav Item C"/>
    </NavigationView.MenuItems>

    <Frame x:Name="ContentFrame"/>
</NavigationView>

Anzeigemodi

Du kannst die PaneDisplayMode-Eigenschaft verwenden, um verschiedene Navigationsstile oder Anzeigemodi für das NavigationView-Element zu konfigurieren.

Oben

Dieser Bereich wird oberhalb des Inhalts positioniert.
PaneDisplayMode="Top"

Beispiel für Navigation oben

Wir empfehlen die Navigation oben, wenn Folgendes gilt:

  • Du hast fünf oder weniger Navigationskategorien der obersten Ebene, die alle die gleiche Wichtigkeit aufweisen. Alle weiteren Navigationskategorien der obersten Ebene, die sich im Dropdown-Überlaufmenü befinden, werden als weniger wichtig angesehen.
  • Du musst alle Navigationsoptionen auf dem Bildschirm anzeigen.
  • Du benötigst mehr Platz für deinen App-Inhalt.
  • Die Navigationskategorien deiner App lassen sich nicht eindeutig durch Symbole darstellen.

Links

Der Bereich wird erweitert und links vom Inhalt positioniert.
PaneDisplayMode="Left"

Beispiel für erweiterten Navigationsbereich auf der linken Seite

Wir empfehlen die Navigation links, wenn Folgendes gilt:

  • Du verfügst über fünf bis zehn Navigationskategorien der obersten Ebene mit gleicher Wichtigkeit.
  • Du möchtest, dass die Navigationskategorien hervorgehoben sind und weniger Platz für anderen App-Inhalt vorhanden ist.

LeftCompact

Im Bereich werden bis zum Öffnen nur Symbole angezeigt, und dann wird er links vom Inhalt angeordnet. Beim Öffnen überlagert der Bereich den Inhalt.
PaneDisplayMode="LeftCompact"

Beispiel für kompakten Navigationsbereich links

LeftMinimal

Bis der Bereich geöffnet wird, wird nur die Menüschaltfläche angezeigt. Beim Öffnen überlagert der Bereich die linke Seite des Inhalts.
PaneDisplayMode="LeftMinimal"

Beispiel für minimalen Navigationsbereich links

Automatisch

Standardmäßig ist „PaneDisplayMode“ auf Auto festgelegt. Im Modus Auto wird „NavigationView“ von LeftMinimal (schmales Fenster) über LeftCompact und schließlich in Left geändert, wenn das Fenster breiter wird. Weitere Informationen findest du im Abschnitt zum adaptiven Verhalten.

Standardnavigation links: adaptives Verhalten
NavigationView: adaptives Standardverhalten

Aufbau

In diesen Abbildungen ist das Layout des Bereichs, der Kopfzeile und des Inhaltsbereichs für das Steuerelement dargestellt, wenn es für die Navigation oben oder links konfiguriert ist.

Top NavigationView-Layout
Layout für Navigation oben

Left NavigationView-Layout
Layout für Navigation links

Bereich

Du kannst die PaneDisplayMode-Eigenschaft verwenden, um den Bereich oberhalb des Inhalts oder links davon anzuordnen.

Der NavigationView-Bereich kann Folgendes enthalten:

Der linke Bereich enthält außerdem Folgendes:

  • Eine Menüschaltfläche zum Öffnen und Schließen des Bereichs. Bei größeren App-Fenstern mit geöffnetem Bereich kannst du diese Schaltfläche mit der IsPaneToggleButtonVisible-Eigenschaft auch ausblenden.

„NavigationView“ verfügt über eine Zurück-Schaltfläche. Diese befindet sich in der linken oberen Ecke des Bereichs. Hiermit wird die Navigation in Rückwärtsrichtung aber nicht automatisch verarbeitet und der Inhalt nicht dem Backstack hinzugefügt. Informationen zum Aktivieren der Rückwärtsnavigation findest du im Abschnitt Rückwärtsnavigation.

Hier ist der ausführliche Seitenaufbau für die Anordnung des Bereichs oben und links dargestellt.

Navigationsbereich oben

NavigationView: Aufbau des oberen Bereichs

  1. Header
  2. Navigationselemente
  3. Trennzeichen
  4. AutoSuggestBox (optional)
  5. Schaltfläche „Einstellungen“ (optional)

Navigationsbereich links

NavigationView: Aufbau des linken Bereichs

  1. Menü-Taste
  2. Navigationselemente
  3. Trennzeichen
  4. Header
  5. AutoSuggestBox (optional)
  6. Schaltfläche „Einstellungen“ (optional)

Sie können FooterMenuItems verwenden, um Navigationselemente an das Ende des Navigationsbereichs zu platzieren (im Gegensatz zur MenuItems-Eigenschaft, mit der Elemente an den Anfang des Bereichs platziert werden).

Das FooterMenuItems-Steuerelement wird standardmäßig vor dem Element Settings angezeigt. Das Settings-Element kann nach wie vor mithilfe der Eigenschaft IsSettingsVisible aktiviert/deaktiviert werden.

In FooterMenuItems-Steuerelemente sollten nur Navigationselemente gesetzt werden. Alle anderen Inhalte, die an der Fußzeile des Bereichs ausgerichtet werden müssen, sollten in das PaneFooter-Steuerelement gesetzt werden.

Ein Beispiel für das Hinzufügen von FooterMenuItems-Steuerelementen zu ihrem NavigationView-Steuerelement finden Sie in der FooterMenuItems-Klasse.

Die folgende Abbildung zeigt ein NavigationView-Steuerelement mit den Navigationselementen Konto, Ihr Warenkorb und Hilfe im Fußzeilenmenü.

NavigationView-Steuerelement mit FooterMenuItems-Steuerelement

Du kannst den Freiforminhalt in der Fußzeile des Bereichs anordnen, indem du ihn der PaneFooter-Eigenschaft hinzufügst.

Bereichsfußzeile für Navigation oben
Bereichsfußzeile für Navigation oben

Bereichsfußzeile für Navigation links
Bereichsfußzeile für Navigation links

Titel und Kopfzeile des Bereichs

Du kannst Textinhalt in der Kopfzeile des Bereichs anordnen, indem du die PaneTitle-Eigenschaft festlegst. Hierbei wird eine Zeichenfolge verwendet und der Text neben der Menüschaltfläche angezeigt.

Zum Hinzufügen von anderen Inhalten als Text, z. B. ein Bild oder Logo, kannst du ein beliebiges Element in der Kopfzeile des Bereichs anordnen, indem du es der PaneHeader-Eigenschaft hinzufügst.

Wenn sowohl „PaneTitle“ als auch „PaneHeader“ festgelegt sind, wird der Inhalt horizontal neben der Menüschaltfläche gestapelt, wobei „PaneTitle“ der Menüschaltfläche am nächsten liegt.

Bereichskopfzeile für Navigation oben
Bereichskopfzeile für Navigation oben

Bereichskopfzeile für Navigation links
Bereichskopfzeile für Navigation links

Bereichsinhalt

Du kannst den Freiforminhalt im Bereich anordnen, indem du ihn der PaneCustomContent-Eigenschaft hinzufügst.

Benutzerdefinierter Bereichsinhalt für Navigation oben
Benutzerdefinierter Bereichsinhalt für Navigation oben

Benutzerdefinierter Bereichsinhalt für Navigation links
Benutzerdefinierter Bereichsinhalt für Navigation links

Du kannst einen Seitentitel hinzufügen, indem du die Header-Eigenschaft festlegst.

Beispiel für NavigationView-Kopfzeilenbereich
NavigationView-Kopfzeile

Der Kopfzeilenbereich ist vertikal an der Position der Navigationsschaltfläche im linken Bereich ausgerichtet und befindet sich unterhalb des obersten Bereichs. Er hat eine feste Höhe von 52 Pixel. Er enthält jeweils den Seitentitel der ausgewählten Navigationskategorie. Die Kopfzeile ist am oberen Rand der Seite angedockt und dient als Scroll-Clipping-Punkt für den Inhaltsbereich.

Die Kopfzeile wird jedes Mal angezeigt, wenn sich „NavigationView“ im Anzeigemodus Minimal befindet. Du kannst die Kopfzeile in anderen Modi ausblenden, die bei größeren Fensterbreiten verwendet werden. Lege zum Ausblenden der Kopfzeile die AlwaysShowHeader-Eigenschaft auf false fest.

Inhalt

Beispiel für NavigationView-Inhaltsbereich
NavigationView-Inhalt

Im Inhaltsbereich werden die meisten Informationen für die ausgewählte Navigationskategorie angezeigt.

Wir empfehlen, Ränder für deinen Inhaltsbereich auf 12 Pixel festzulegen, wenn sich „NavigationView“ im Modus Minimal befindet. Verwende andernfalls 24 Pixel.

Adaptives Verhalten

Der Anzeigemodus von „NavigationView“ ändert sich standardmäßig automatisch je nach verfügbarem Platz auf dem Bildschirm. Die Eigenschaften CompactModeThresholdWidth und ExpandedModeThresholdWidth geben die Haltepunkte an, an denen sich der Anzeigemodus ändert. Du kannst diese Werte ändern, um das Verhalten des adaptiven Anzeigemodus anzupassen.

Standardwert

Wenn PaneDisplayMode auf den Standardwert Auto festgelegt ist, wird beim adaptiven Verhalten Folgendes angezeigt:

  • Ein erweiterter Bereich auf der linken Seite bei höheren Fensterbreiten (1008 Pixel oder mehr)
  • Ein Navigationsbereich nur für Symbole auf der linken Seite (LeftCompact) bei mittleren Fensterbreiten (641 bis 1.007 Pixel).
  • Nur eine Menüschaltfläche (LeftMinimal) bei kleinen Fensterbreiten (640 Pixel oder weniger).

Weitere Informationen zu Fenstergrößen für adaptives Verhalten findest du unter Bildschirmgrößen und Haltepunkte.

Standardnavigation links: adaptives Verhalten
NavigationView: adaptives Standardverhalten

Minimal

Ein zweites gängiges adaptives Muster ist die Verwendung eines erweiterten Bereichs auf der linken Seite bei höheren Fensterbreiten und nur einer Menüschaltfläche bei mittleren und geringen Fensterbreiten.

Dies empfehlen wir in folgenden Fällen:

  • Du benötigst mehr Platz für App-Inhalt bei geringeren Fensterbreiten.
  • Deine Navigationskategorien lassen sich durch Symbole nicht eindeutig darstellen.

Navigation links „Minimal“: adaptives Verhalten
NavigationView: minimales adaptives Verhalten

Lege zum Konfigurieren dieses Verhaltens „CompactModeThresholdWidth“ auf die Breite fest, die für die Reduzierung des Bereichs verwendet werden soll. Hier wurde der Standardwert 640 in 1.007 geändert. Du kannst auch „ExpandedModeThresholdWidth“ festlegen, um sicherzustellen, dass es für die Werte nicht zu einem Konflikt kommt.

<NavigationView CompactModeThresholdWidth="1007" ExpandedModeThresholdWidth="1007"/>

Kompakt

Ein drittes gängiges adaptives Muster ist die Verwendung eines erweiterten Bereichs auf der linken Seite bei höheren Fensterbreiten und eines Navigationsbereichs vom Typ „LeftCompact“ nur für Symbole bei mittleren und geringen Fensterbreiten.

Dies empfehlen wir in folgenden Fällen:

  • Es ist wichtig, dass immer alle Navigationsoptionen auf dem Bildschirm angezeigt werden.
  • Deine Navigationskategorien lassen sich durch Symbole eindeutig darstellen.

Navigation links „Kompakt“: adaptives Verhalten
NavigationView: kompaktes adaptives Verhalten

Lege zum Konfigurieren dieses Verhaltens „CompactModeThresholdWidth“ auf „0“ fest.

<NavigationView CompactModeThresholdWidth="0"/>

Kein adaptives Verhalten

Legen Sie „PaneDisplayMode“ auf einen anderen Wert als Auto fest, um das automatische adaptive Verhalten zu deaktivieren. Hier ist „LeftMinimal“ festgelegt, sodass unabhängig von der Fensterbreite nur die Menüschaltfläche angezeigt wird.

Navigation links: kein adaptives Verhalten
NavigationView: „PaneDisplayMode“ auf „LeftMinimal“ festgelegt

<NavigationView PaneDisplayMode="LeftMinimal" />

Wie oben im Abschnitt Anzeigemodi beschrieben, kannst du für den Bereich „Immer oben“, „Immer erweitert“, „Immer kompakt“ oder „Immer minimal“ festlegen. Du kann die Anzeigemodi auch selbst in deinem App-Code verwalten. Ein Beispiel hierfür ist im nächsten Abschnitt enthalten.

Von Navigation oben zu Navigation links

Wenn du in deiner App die Navigation „oben“ verwendest, werden die Navigationselemente zu einem Überlaufmenü reduziert, wenn sich die Fensterbreite verringert. Falls Ihr App-Fenster schmal ist, kann die Benutzerfreundlichkeit durch das Umschalten von „PaneDisplayMode“ für die Navigation von Top auf LeftMinimal erhöht werden, anstatt zuzulassen, dass alle Elemente zu einem Überlaufmenü reduziert werden.

Wir empfehlen die Verwendung der Navigation „oben“ bei großen Fenstern und die Navigation „links“ bei kleinen Fenstern, wenn Folgendes gilt:

  • Du verfügst über mehrere Navigationskategorien der obersten Ebene mit gleicher Wichtigkeit, die zusammen angezeigt werden sollen. Wenn eine Kategorie dieser Gruppe nicht auf den Bildschirm passt, wird eine Reduzierung auf den Navigationsbereich links durchgeführt, um die gleiche Wichtigkeit sicherzustellen.
  • Du möchtest bei kleinen Fenstern für Inhalt so viel Platz wie möglich bereitstellen.

In diesem Beispiel wird gezeigt, wie Sie eine VisualStateManager- und AdaptiveTrigger.MinWindowWidth-Eigenschaft verwenden, um zwischen den Navigationstypen Top und LeftMinimal zu wechseln.

Beispiel für adaptives Verhalten „oben“ oder „links“: 1

<Grid>
    <NavigationView x:Name="NavigationViewControl" >
        <NavigationView.MenuItems>
            <NavigationViewItem Content="A" x:Name="A" />
            <NavigationViewItem Content="B" x:Name="B" />
            <NavigationViewItem Content="C" x:Name="C" />
        </NavigationView.MenuItems>
    </NavigationView>

    <VisualStateManager.VisualStateGroups>
        <VisualStateGroup>
            <VisualState>
                <VisualState.StateTriggers>
                    <AdaptiveTrigger
                        MinWindowWidth="{x:Bind NavigationViewControl.CompactModeThresholdWidth}" />
                </VisualState.StateTriggers>

                <VisualState.Setters>
                    <Setter Target="NavigationViewControl.PaneDisplayMode" Value="Top"/>
                </VisualState.Setters>
            </VisualState>
        </VisualStateGroup>
    </VisualStateManager.VisualStateGroups>
</Grid>

Tipp

Wenn du „AdaptiveTrigger.MinWindowWidth“ verwendest, wird der visuelle Zustand ausgelöst, falls das Fenster breiter als die angegebene Mindestbreite ist. Dies bedeutet, dass mit dem XAML-Standardcode das schmale Fenster definiert wird und mit „VisualState“ die Änderungen definiert werden, die angewendet werden, wenn das Fenster breiter wird. Der Standardmodus „PaneDisplayMode“ für „NavigationView“ lautet „Auto“. Wenn die Fensterbreite kleiner oder gleich CompactModeThresholdWidth ist, wird somit die Navigation vom Typ LeftMinimal verwendet. Wenn das Fenster breiter wird, wird der Standardwert mit „VisualState“ überschrieben und die Navigation Top verwendet.

Von „NavigationView“ werden keine Navigationsaufgaben automatisch ausgeführt. Wenn der Benutzer auf ein Navigationselement tippt, wird es von „NavigationView“ als ausgewählt angezeigt, und ein Ereignis vom Typ ItemInvoked wird ausgelöst. Falls der Tippvorgang zur Auswahl eines neuen Elements führt, wird auch ein SelectionChanged-Ereignis ausgelöst.

Du kannst beide Ereignisse verarbeiten, um Aufgaben für die angeforderte Navigation durchzuführen. Welches Ereignis verarbeitet werden sollte, hängt von dem Verhalten ab, das für deine App gelten soll. Normalerweise wird als Reaktion auf diese Ereignisse zur angeforderten Seite navigiert und die NavigationView-Kopfzeile aktualisiert.

  • ItemInvoked wird immer ausgelöst, wenn der Benutzer auf ein Navigationselement tippt – auch wenn es bereits ausgewählt ist. (Das Element kann auch mit einer entsprechenden Aktion mit Maus, Tastatur oder einer anderen Eingabemethode aufgerufen werden. Weitere Informationen finden Sie unter Eingabe und Interaktionen.) Wenn Sie im ItemInvoked-Handler navigieren, wird die Seite standardmäßig neu geladen, und dem Navigationsstapel wird ein doppelter Eintrag hinzugefügt. Für das Navigieren während eines Elementaufrufs solltest du das erneute Laden der Seite nicht zulassen oder sicherstellen, dass im Backstack der Navigation beim erneuten Laden der Seite kein doppelter Eintrag erstellt wird. (Siehe Codebeispiele.)
  • SelectionChanged kann von einem Benutzer ausgelöst werden, der ein derzeit nicht ausgewähltes Element aufruft, oder indem das ausgewählte Element programmgesteuert geändert wird. Wenn die Änderung der Auswahl erfolgt, weil ein Benutzer ein Element aufgerufen hat, tritt das ItemInvoked-Ereignis zuerst ein. Bei einer programmgesteuerten Änderung der Auswahl wird das ItemInvoked-Ereignis nicht ausgelöst.

Alle Navigationselemente sind Teil desselben Auswahlmodells, egal ob sie Teil von MenuItems oder FooterMenuItems sind. Es kann immer nur ein Navigationselement ausgewählt werden.

Rückwärtsnavigation

„NavigationView“ verfügt über eine integrierte Zurück-Schaltfläche. Wie bei der Vorwärtsnavigation auch, wird die Rückwärtsnavigation aber nicht automatisch durchgeführt. Wenn der Benutzer auf die Zurück-Schaltfläche tippt, wird das BackRequested-Ereignis ausgelöst. Du verarbeitest dieses Ereignis, um die Rückwärtsnavigation durchzuführen. Weitere Informationen und Codebeispiele findest du unter Navigationsverlauf und Rückwärtsnavigation für UWP-Apps.

Im Modus Minimal oder Compact ist das NavigationView-Steuerelement Pane als Flyout geöffnet. In diesem Fall wird Pane durch das Klicken auf die Zurück-Schaltfläche geschlossen und stattdessen das PaneClosing-Ereignis ausgelöst.

Du kannst die Zurück-Schaltfläche ausblenden oder deaktivieren, indem du diese Eigenschaften festlegst:

  • IsBackButtonVisible: Dient zum Ein- und Ausblenden der Zurück-Schaltfläche. Für diese Eigenschaft wird ein Wert der NavigationViewBackButtonVisible-Enumeration verwendet, der standardmäßig auf Auto festgelegt ist. Wenn die Schaltfläche reduziert ist, wird im Layout dafür kein Platz reserviert.
  • IsBackEnabled: Dient zum Aktivieren und Deaktivieren der Zurück-Schaltfläche. Du kannst für diese Eigenschaft eine Datenbindung an die CanGoBack-Eigenschaft deines Navigationsrahmens durchführen. BackRequested wird nicht ausgelöst, wenn IsBackEnabled auf false festgelegt ist.

NavigationView: Zurück-Schaltfläche im linken Navigationsbereich
Schaltfläche „Zurück“ im linken Navigationsbereich

NavigationView: Zurück-Schaltfläche im oberen Navigationsbereich
Schaltfläche „Zurück“ im oberen Navigationsbereich

Codebeispiel

In diesem Beispiel wird veranschaulicht, wie du „NavigationView“ sowohl mit einem oberen Navigationsbereich für große Fenster als auch mit einem linken Navigationsbereich für kleine Fenster verwenden kannst. Du kannst eine Umstellung durchführen, bei der nur die Navigation links verwendet wird, indem du in VisualStateManager die Navigationseinstellungen für top entfernst.

Das Beispiel veranschaulicht eine häufige Vorgehensweise zum Einrichten von Navigationsdaten, die für viele Szenarien geeignet ist. In diesem Beispiel speichern Sie als Erstes (im Tag des Elements NavigationViewItem) den vollständigen Typnamen der Seite, auf die Sie navigieren möchten. Im Handler führen Sie das Unboxing für diesen Wert durch, wandeln ihn in ein Type(C#)- oder Windows::UI::Xaml::Interop::TypeName(C++/WinRT)-Objekt um und verwenden dieses Objekt, um zur Zielseite zu navigieren. Auf diese Weise können Sie Komponententests erstellen, um zu bestätigen, dass die Werte in Ihren Tags einen gültigen Typ aufweisen. (Weitere Informationen finden Sie auch unter Boxing und Unboxing von Werten für „IInspectable“ mit C++/WinRT.) Darüber hinaus wird veranschaulicht, wie Sie die Rückwärtsnavigation mit der Zurück-Schaltfläche von „NavigationView“ implementieren.

In diesem Code wird vorausgesetzt, dass deine App Seiten mit den folgenden Namen enthält, auf die navigiert werden kann: HomePage, AppsPage, GamesPage, MusicPage, MyContentPage und SettingsPage. Der Code für diese Seiten ist nicht angegeben.

<Page ... >
 <Grid>
     <NavigationView x:Name="NavView"
                     Loaded="NavView_Loaded"
                     ItemInvoked="NavView_ItemInvoked"
                     BackRequested="NavView_BackRequested">
         <NavigationView.MenuItems>
             <NavigationViewItem Tag="NavigationViewDemo.HomePage" Icon="Home" Content="Home"/>
             <NavigationViewItemSeparator/>
             <NavigationViewItemHeader x:Name="MainPagesHeader"
                                       Content="Main pages"/>
             <NavigationViewItem Tag="NavigationViewDemo.AppsPage" Content="Apps">
                 <NavigationViewItem.Icon>
                     <FontIcon Glyph="&#xEB3C;"/>
                 </NavigationViewItem.Icon>
             </NavigationViewItem>
             <NavigationViewItem Tag="NavigationViewDemo.GamesPage" Content="Games">
                 <NavigationViewItem.Icon>
                     <FontIcon Glyph="&#xE7FC;"/>
                 </NavigationViewItem.Icon>
             </NavigationViewItem>
             <NavigationViewItem Tag="NavigationViewDemo.MusicPage" Icon="Audio" Content="Music"/>
         </NavigationView.MenuItems>

         <NavigationView.AutoSuggestBox>
             <!-- See AutoSuggestBox documentation for
              more info about how to implement search. -->
             <AutoSuggestBox x:Name="NavViewSearchBox" QueryIcon="Find"/>
         </NavigationView.AutoSuggestBox>

         <ScrollViewer>
             <Frame x:Name="ContentFrame" IsTabStop="True"
                NavigationFailed="ContentFrame_NavigationFailed"/>
         </ScrollViewer>
     </NavigationView>

     <VisualStateManager.VisualStateGroups>
         <VisualStateGroup>
             <VisualState>
                 <VisualState.StateTriggers>
                     <AdaptiveTrigger
                     MinWindowWidth="{x:Bind NavViewCompactModeThresholdWidth}"/>
                 </VisualState.StateTriggers>
                 <VisualState.Setters>
                     <!-- Remove the next 3 lines for left-only navigation. -->
                     <Setter Target="NavView.PaneDisplayMode" Value="Top"/>
                     <Setter Target="NavViewSearchBox.Width" Value="200"/>
                     <Setter Target="MainPagesHeader.Visibility" Value="Collapsed"/>
                     <!-- Leave the next line for left-only navigation. -->
                     <Setter Target="ContentFrame.Padding" Value="24,0,24,24"/>
                 </VisualState.Setters>
             </VisualState>
         </VisualStateGroup>
     </VisualStateManager.VisualStateGroups>
 </Grid>
</Page>
private double NavViewCompactModeThresholdWidth { get { return NavView.CompactModeThresholdWidth; } }

private void ContentFrame_NavigationFailed(object sender, NavigationFailedEventArgs e)
{
    throw new Exception("Failed to load Page " + e.SourcePageType.FullName);
}

private void NavView_Loaded(object sender, RoutedEventArgs e)
{
    // You can also add items in code.
    NavView.MenuItems.Add(new NavigationViewItemSeparator());
    NavView.MenuItems.Add(new NavigationViewItem
    {
        Content = "My content",
        Icon = new SymbolIcon((Symbol)0xF1AD),
        Tag = "NavigationViewDemo.MyContentPage"
    });

    // Add handler for ContentFrame navigation.
    ContentFrame.Navigated += On_Navigated;

    // NavView doesn't load any page by default, so load home page.
    NavView.SelectedItem = NavView.MenuItems[0];
    // If navigation occurs on SelectionChanged, this isn't needed.
    // Because we use ItemInvoked to navigate, we need to call Navigate
    // here to load the home page.
    NavView_Navigate(typeof(HomePage), new EntranceNavigationTransitionInfo());
}

private void NavView_ItemInvoked(NavigationView sender,
                                 NavigationViewItemInvokedEventArgs args)
{
    if (args.IsSettingsInvoked == true)
    {
        NavView_Navigate(typeof(SettingsPage), args.RecommendedNavigationTransitionInfo);
    }
    else if (args.InvokedItemContainer != null)
    {
        Type navPageType = Type.GetType(args.InvokedItemContainer.Tag.ToString());
        NavView_Navigate(navPageType, args.RecommendedNavigationTransitionInfo);
    }
}

// NavView_SelectionChanged is not used in this example, but is shown for completeness.
// You will typically handle either ItemInvoked or SelectionChanged to perform navigation,
// but not both.
private void NavView_SelectionChanged(NavigationView sender,
                                      NavigationViewSelectionChangedEventArgs args)
{
    if (args.IsSettingsSelected == true)
    {
        NavView_Navigate(typeof(SettingsPage), args.RecommendedNavigationTransitionInfo);
    }
    else if (args.SelectedItemContainer != null)
    {
        Type navPageType = Type.GetType(args.SelectedItemContainer.Tag.ToString());
        NavView_Navigate(navPageType, args.RecommendedNavigationTransitionInfo);
    }
}

private void NavView_Navigate(
    Type navPageType,
    NavigationTransitionInfo transitionInfo)
{
    // Get the page type before navigation so you can prevent duplicate
    // entries in the backstack.
    Type preNavPageType = ContentFrame.CurrentSourcePageType;

    // Only navigate if the selected page isn't currently loaded.
    if (navPageType is not null && !Type.Equals(preNavPageType, navPageType))
    {
        ContentFrame.Navigate(navPageType, null, transitionInfo);
    }
}

private void NavView_BackRequested(NavigationView sender,
                                   NavigationViewBackRequestedEventArgs args)
{
    TryGoBack();
}

private bool TryGoBack()
{
    if (!ContentFrame.CanGoBack)
        return false;

    // Don't go back if the nav pane is overlayed.
    if (NavView.IsPaneOpen &&
        (NavView.DisplayMode == NavigationViewDisplayMode.Compact ||
         NavView.DisplayMode == NavigationViewDisplayMode.Minimal))
        return false;

    ContentFrame.GoBack();
    return true;
}

private void On_Navigated(object sender, NavigationEventArgs e)
{
    NavView.IsBackEnabled = ContentFrame.CanGoBack;

    if (ContentFrame.SourcePageType == typeof(SettingsPage))
    {
        // SettingsItem is not part of NavView.MenuItems, and doesn't have a Tag.
        NavView.SelectedItem = (NavigationViewItem)NavView.SettingsItem;
        NavView.Header = "Settings";
    }
    else if (ContentFrame.SourcePageType != null)
    {
        // Select the nav view item that corresponds to the page being navigated to.
        NavView.SelectedItem = NavView.MenuItems
                    .OfType<NavigationViewItem>()
                    .First(i => i.Tag.Equals(ContentFrame.SourcePageType.FullName.ToString()));

        NavView.Header =
            ((NavigationViewItem)NavView.SelectedItem)?.Content?.ToString();

    }
}
// MainPage.idl
runtimeclass MainPage : Microsoft.UI.Xaml.Controls.Page
{
    ...
    Double NavViewCompactModeThresholdWidth{ get; };
}

// pch.h
...
#include <winrt/Windows.UI.Xaml.Interop.h>
#include <winrt/Microsoft.UI.Xaml.Media.Animation.h>


// MainPage.h
#pragma once

#include "MainPage.g.h"

namespace muxc
{
    using namespace winrt::Microsoft::UI::Xaml::Controls;
};

namespace winrt::NavigationViewDemo::implementation
{
    struct MainPage : MainPageT<MainPage>
    {
        MainPage();

        double NavViewCompactModeThresholdWidth();
        void ContentFrame_NavigationFailed(
            Windows::Foundation::IInspectable const& /* sender */,
            Microsoft::UI::Xaml::Navigation::NavigationFailedEventArgs const& args);
        void NavView_Loaded(
            Windows::Foundation::IInspectable const& /* sender */,
            Microsoft::UI::Xaml::RoutedEventArgs const& /* args */);
        void NavView_ItemInvoked(
            Windows::Foundation::IInspectable const& /* sender */,
            muxc::NavigationViewItemInvokedEventArgs const& args);

        // NavView_SelectionChanged is not used in this example, but is shown for completeness.
        // You'll typically handle either ItemInvoked or SelectionChanged to perform navigation,
        // but not both.
        void NavView_SelectionChanged(
            muxc::NavigationView const& /* sender */,
            muxc::NavigationViewSelectionChangedEventArgs const& args);
        void NavView_Navigate(
            Windows::UI::Xaml::Interop::TypeName navPageType,
            Microsoft::UI::Xaml::Media::Animation::NavigationTransitionInfo const& transitionInfo);
        void NavView_BackRequested(
            muxc::NavigationView const& /* sender */,
            muxc::NavigationViewBackRequestedEventArgs const& /* args */);
        void On_Navigated(
            Windows::Foundation::IInspectable const& /* sender */,
            Microsoft::UI::Xaml::Navigation::NavigationEventArgs const& args);
        bool TryGoBack();

    private:

    };
}

namespace winrt::NavigationViewDemo::factory_implementation
{
    struct MainPage : MainPageT<MainPage, implementation::MainPage>
    {
    };
}

// MainPage.cpp
#include "pch.h"
#include "MainPage.xaml.h"
#if __has_include("MainPage.g.cpp")
#include "MainPage.g.cpp"
#endif

using namespace winrt;
using namespace Microsoft::UI::Xaml;

namespace winrt::NavigationViewDemo::implementation
{
    MainPage::MainPage()
    {
        InitializeComponent();
    }

    double MainPage::NavViewCompactModeThresholdWidth()
    {
        return NavView().CompactModeThresholdWidth();
    }

    void MainPage::ContentFrame_NavigationFailed(
        Windows::Foundation::IInspectable const& /* sender */,
        Microsoft::UI::Xaml::Navigation::NavigationFailedEventArgs const& args)
    {
        throw winrt::hresult_error(
            E_FAIL, winrt::hstring(L"Failed to load Page ") + args.SourcePageType().Name);
    }

    void MainPage::NavView_Loaded(
        Windows::Foundation::IInspectable const& /* sender */,
        Microsoft::UI::Xaml::RoutedEventArgs const& /* args */)
    {
        // You can also add items in code.
        NavView().MenuItems().Append(muxc::NavigationViewItemSeparator());
        muxc::NavigationViewItem navigationViewItem;
        navigationViewItem.Content(winrt::box_value(L"My content"));
        navigationViewItem.Icon(muxc::SymbolIcon(static_cast<muxc::Symbol>(0xF1AD)));
        navigationViewItem.Tag(winrt::box_value(L"NavigationViewDemo.MyContentPage"));
        NavView().MenuItems().Append(navigationViewItem);

        // Add handler for ContentFrame navigation.
        ContentFrame().Navigated({ this, &MainPage::On_Navigated });

        // NavView doesn't load any page by default, so load home page.
        NavView().SelectedItem(NavView().MenuItems().GetAt(0));
        // If navigation occurs on SelectionChanged, then this isn't needed.
        // Because we use ItemInvoked to navigate, we need to call Navigate
        // here to load the home page.
        NavView_Navigate(winrt::xaml_typename<NavigationViewDemo::HomePage>(),
            Microsoft::UI::Xaml::Media::Animation::EntranceNavigationTransitionInfo());
    }

    void MainPage::NavView_ItemInvoked(
        Windows::Foundation::IInspectable const& /* sender */,
        muxc::NavigationViewItemInvokedEventArgs const& args)
    {
        if (args.IsSettingsInvoked())
        {
            NavView_Navigate(winrt::xaml_typename<NavigationViewDemo::SettingsPage>(),
                args.RecommendedNavigationTransitionInfo());
        }
        else if (args.InvokedItemContainer())
        {
            Windows::UI::Xaml::Interop::TypeName pageTypeName;
            pageTypeName.Name = unbox_value<hstring>(args.InvokedItemContainer().Tag());
            pageTypeName.Kind = Windows::UI::Xaml::Interop::TypeKind::Primitive;
            NavView_Navigate(pageTypeName, args.RecommendedNavigationTransitionInfo());
        }
    }

    // NavView_SelectionChanged is not used in this example, but is shown for completeness.
    // You will typically handle either ItemInvoked or SelectionChanged to perform navigation,
    // but not both.
    void MainPage::NavView_SelectionChanged(
        muxc::NavigationView const& /* sender */,
        muxc::NavigationViewSelectionChangedEventArgs const& args)
    {
        if (args.IsSettingsSelected())
        {
            NavView_Navigate(winrt::xaml_typename<NavigationViewDemo::SettingsPage>(),
                args.RecommendedNavigationTransitionInfo());
        }
        else if (args.SelectedItemContainer())
        {
            Windows::UI::Xaml::Interop::TypeName pageTypeName;
            pageTypeName.Name = unbox_value<hstring>(args.SelectedItemContainer().Tag());
            pageTypeName.Kind = Windows::UI::Xaml::Interop::TypeKind::Primitive;
            NavView_Navigate(pageTypeName, args.RecommendedNavigationTransitionInfo());
        }
    }

    void MainPage::NavView_Navigate(
        Windows::UI::Xaml::Interop::TypeName navPageType,
        Microsoft::UI::Xaml::Media::Animation::NavigationTransitionInfo const& transitionInfo)
    {
        // Get the page type before navigation so you can prevent duplicate
        // entries in the backstack.
        Windows::UI::Xaml::Interop::TypeName preNavPageType =
            ContentFrame().CurrentSourcePageType();

        // Navigate only if the selected page isn't currently loaded.
        if (navPageType.Name != L"" && preNavPageType.Name != navPageType.Name)
        {
            ContentFrame().Navigate(navPageType, nullptr, transitionInfo);
        }
    }

    void MainPage::NavView_BackRequested(
        muxc::NavigationView const& /* sender */,
        muxc::NavigationViewBackRequestedEventArgs const& /* args */)
    {
        TryGoBack();
    }

    bool MainPage::TryGoBack()
    {
        if (!ContentFrame().CanGoBack())
            return false;
        // Don't go back if the nav pane is overlayed.
        if (NavView().IsPaneOpen() &&
            (NavView().DisplayMode() == muxc::NavigationViewDisplayMode::Compact ||
                NavView().DisplayMode() == muxc::NavigationViewDisplayMode::Minimal))
            return false;
        ContentFrame().GoBack();
        return true;
    }

    void MainPage::On_Navigated(
        Windows::Foundation::IInspectable const& /* sender */,
        Microsoft::UI::Xaml::Navigation::NavigationEventArgs const& args)
    {
        NavView().IsBackEnabled(ContentFrame().CanGoBack());

        if (ContentFrame().SourcePageType().Name ==
            winrt::xaml_typename<NavigationViewDemo::SettingsPage>().Name)
        {
            // SettingsItem is not part of NavView.MenuItems, and doesn't have a Tag.
            NavView().SelectedItem(NavView().SettingsItem().as<muxc::NavigationViewItem>());
            NavView().Header(winrt::box_value(L"Settings"));
        }
        else if (ContentFrame().SourcePageType().Name != L"")
        {
            for (auto&& eachMenuItem : NavView().MenuItems())
            {
                auto navigationViewItem =
                    eachMenuItem.try_as<muxc::NavigationViewItem>();
                {
                    if (navigationViewItem)
                    {
                        winrt::hstring hstringValue =
                            winrt::unbox_value_or<winrt::hstring>(
                                navigationViewItem.Tag(), L"");
                        if (hstringValue == ContentFrame().SourcePageType().Name)
                        {
                            NavView().SelectedItem(navigationViewItem);
                            NavView().Header(navigationViewItem.Content());
                        }
                    }
                }
            }
        }
    }
}

Hierarchische Navigation

Einige Apps verfügen möglicherweise über eine komplexere hierarchische Struktur, die mehr als nur eine flache Liste von Navigationselementen erfordert. Möglicherweise möchten Sie Navigationselemente auf oberster Ebene verwenden, um Seitenkategorien anzuzeigen, und untergeordnete Elemente, um bestimmte Seiten anzuzeigen. Dies ist auch nützlich, wenn Sie über Seiten im Hub-Format verfügen, die nur als Link zu anderen Seiten dienen. In solchen Fällen sollten Sie eine hierarchische Navigationsansicht erstellen.

Verwenden Sie entweder die MenuItems-Eigenschaft oder die MenuItemsSource-Eigenschaft von NavigationViewItem, um eine hierarchische Liste von verschachtelten Navigationselementen im Fensterbereich anzuzeigen. Jedes NavigationViewItem kann andere NavigationViewItems und Organisationselemente wie Elementheader und Trennzeichen enthalten. Um bei Verwendung von MenuItemsSource eine hierarchische Liste anzuzeigen, legen Sie ItemTemplate als NavigationViewItem fest, und binden Sie seine MenuItemsSource-Eigenschaft an die nächste Ebene der Hierarchie.

Obwohl NavigationViewItem beliebig viele verschachtelte Ebenen enthalten kann, empfehlen wir, die Navigationshierarchie Ihrer App flach zu halten. Wir glauben, dass zwei Ebenen zum Zwecke der Verwendbarkeit und des Verständnisses ideal sind.

„NavigationView“ zeigt die Hierarchie in den Bereichsanzeigemodi Top, Left und LeftCompact an. Im folgenden sehen Sie, wie eine erweiterte Unterstruktur in den einzelnen Bereichsanzeigemodi aussieht:

NavigationView mit Hierarchie

Hinzufügen einer Hierarchie von Elementen im Markup

In diesem Beispiel wird gezeigt, wie Sie die hierarchische App-Navigation im XAML-Markup deklarieren.

<NavigationView>
    <NavigationView.MenuItems>
        <NavigationViewItem Content="Home" Icon="Home" ToolTipService.ToolTip="Home"/>
        <NavigationViewItem Content="Collections" Icon="Keyboard" ToolTipService.ToolTip="Collections">
            <NavigationViewItem.MenuItems>
                <NavigationViewItem Content="Notes" Icon="Page" ToolTipService.ToolTip="Notes"/>
                <NavigationViewItem Content="Mail" Icon="Mail" ToolTipService.ToolTip="Mail"/>
            </NavigationViewItem.MenuItems>
        </NavigationViewItem>
    </NavigationView.MenuItems>
</NavigationView>

Hinzufügen einer Hierarchie von Elementen mithilfe der Datenbindung

Fügen Sie NavigationView eine Hierarchie von Menüelementen hinzu, durch

  • Binden der MenuItemsSource-Eigenschaft an die hierarchischen Daten
  • Definieren der Elementvorlage als NavigationViewMenuItem, wobei als sein Inhalt die Bezeichnung des Menüelements festgelegt ist und seine MenuItemsSource-Eigenschaft an die nächste Ebene der Hierarchie gebunden ist

Dieses Beispiel veranschaulicht auch das Erweitern und Reduzieren von Ereignissen. Diese Ereignisse werden für ein Menüelement mit untergeordneten Elementen ausgelöst.

<Page ... >
    <Page.Resources>
        <DataTemplate x:Key="NavigationViewMenuItem" x:DataType="local:Category">
            <NavigationViewItem Content="{x:Bind Name}" MenuItemsSource="{x:Bind Children}"/>
        </DataTemplate>
    </Page.Resources>

    <Grid>
        <NavigationView x:Name="navview"
    MenuItemsSource="{x:Bind Categories, Mode=OneWay}"
    MenuItemTemplate="{StaticResource NavigationViewMenuItem}"
    ItemInvoked="{x:Bind OnItemInvoked}"
    Expanding="OnItemExpanding"
    Collapsed="OnItemCollapsed"
    PaneDisplayMode="Left">
            <StackPanel Margin="10,10,0,0">
                <TextBlock Margin="0,10,0,0" x:Name="ExpandingItemLabel" Text="Last Expanding: N/A"/>
                <TextBlock x:Name="CollapsedItemLabel" Text="Last Collapsed: N/A"/>
            </StackPanel>
        </NavigationView>
    </Grid>
</Page>
public class Category
{
    public String Name { get; set; }
    public String CategoryIcon { get; set; }
    public ObservableCollection<Category> Children { get; set; }
}

public sealed partial class HierarchicalNavigationViewDataBinding : Page
{
    public HierarchicalNavigationViewDataBinding()
    {
        this.InitializeComponent();
    }

    public ObservableCollection<Category> Categories = new ObservableCollection<Category>()
    {
        new Category(){
            Name = "Menu item 1",
            CategoryIcon = "Icon",
            Children = new ObservableCollection<Category>() {
                new Category(){
                    Name = "Menu item 2",
                    CategoryIcon = "Icon",
                    Children = new ObservableCollection<Category>() {
                        new Category() {
                            Name  = "Menu item 3",
                            CategoryIcon = "Icon",
                            Children = new ObservableCollection<Category>() {
                                new Category() { Name  = "Menu item 4", CategoryIcon = "Icon" },
                                new Category() { Name  = "Menu item 5", CategoryIcon = "Icon" }
                            }
                        }
                    }
                }
            }
        },
        new Category(){
            Name = "Menu item 6",
            CategoryIcon = "Icon",
            Children = new ObservableCollection<Category>() {
                new Category(){
                    Name = "Menu item 7",
                    CategoryIcon = "Icon",
                    Children = new ObservableCollection<Category>() {
                        new Category() { Name  = "Menu item 8", CategoryIcon = "Icon" },
                        new Category() { Name  = "Menu item 9", CategoryIcon = "Icon" }
                    }
                }
            }
        },
        new Category(){ Name = "Menu item 10", CategoryIcon = "Icon" }
    };

    private void OnItemInvoked(object sender, NavigationViewItemInvokedEventArgs e)
    {
        var clickedItem = e.InvokedItem;
        var clickedItemContainer = e.InvokedItemContainer;
    }
    private void OnItemExpanding(object sender, NavigationViewItemExpandingEventArgs e)
    {
        var nvib = e.ExpandingItemContainer;
        var name = "Last expanding: " + nvib.Content.ToString();
        ExpandingItemLabel.Text = name;
    }
    private void OnItemCollapsed(object sender, NavigationViewItemCollapsedEventArgs e)
    {
        var nvib = e.CollapsedItemContainer;
        var name = "Last collapsed: " + nvib.Content;
        CollapsedItemLabel.Text = name;
    }
}
// Category.idl
namespace HierarchicalNavigationViewDataBinding
{
    runtimeclass Category
    {
        String Name;
        String CategoryIcon;
        Windows.Foundation.Collections.IObservableVector<Category> Children;
    }
}

// Category.h
#pragma once
#include "Category.g.h"

namespace winrt::HierarchicalNavigationViewDataBinding::implementation
{
    struct Category : CategoryT<Category>
    {
        Category();
        Category(winrt::hstring name,
            winrt::hstring categoryIcon,
            Windows::Foundation::Collections::
                IObservableVector<HierarchicalNavigationViewDataBinding::Category> children);

        winrt::hstring Name();
        void Name(winrt::hstring const& value);
        winrt::hstring CategoryIcon();
        void CategoryIcon(winrt::hstring const& value);
        Windows::Foundation::Collections::
            IObservableVector<HierarchicalNavigationViewDataBinding::Category> Children();
        void Children(Windows::Foundation::Collections:
            IObservableVector<HierarchicalNavigationViewDataBinding::Category> const& value);

    private:
        winrt::hstring m_name;
        winrt::hstring m_categoryIcon;
        Windows::Foundation::Collections::
            IObservableVector<HierarchicalNavigationViewDataBinding::Category> m_children;
    };
}

// Category.cpp
#include "pch.h"
#include "Category.h"
#include "Category.g.cpp"

namespace winrt::HierarchicalNavigationViewDataBinding::implementation
{
    Category::Category()
    {
        m_children = winrt::single_threaded_observable_vector<HierarchicalNavigationViewDataBinding::Category>();
    }

    Category::Category(
        winrt::hstring name,
        winrt::hstring categoryIcon,
        Windows::Foundation::Collections::
            IObservableVector<HierarchicalNavigationViewDataBinding::Category> children)
    {
        m_name = name;
        m_categoryIcon = categoryIcon;
        m_children = children;
    }

    hstring Category::Name()
    {
        return m_name;
    }

    void Category::Name(hstring const& value)
    {
        m_name = value;
    }

    hstring Category::CategoryIcon()
    {
        return m_categoryIcon;
    }

    void Category::CategoryIcon(hstring const& value)
    {
        m_categoryIcon = value;
    }

    Windows::Foundation::Collections::IObservableVector<HierarchicalNavigationViewDataBinding::Category>
        Category::Children()
    {
        return m_children;
    }

    void Category::Children(
        Windows::Foundation::Collections::IObservableVector<HierarchicalNavigationViewDataBinding::Category>
            const& value)
    {
        m_children = value;
    }
}

// MainPage.idl
import "Category.idl";

namespace HierarchicalNavigationViewDataBinding
{
    [default_interface]
    runtimeclass MainPage : Windows.UI.Xaml.Controls.Page
    {
        MainPage();
        Windows.Foundation.Collections.IObservableVector<Category> Categories{ get; };
    }
}

// MainPage.h
#pragma once

#include "MainPage.g.h"

namespace muxc
{
    using namespace winrt::Microsoft::UI::Xaml::Controls;
};

namespace winrt::HierarchicalNavigationViewDataBinding::implementation
{
    struct MainPage : MainPageT<MainPage>
    {
        MainPage();

        Windows::Foundation::Collections::IObservableVector<HierarchicalNavigationViewDataBinding::Category>
            Categories();

        void OnItemInvoked(muxc::NavigationView const& sender, muxc::NavigationViewItemInvokedEventArgs const& args);
        void OnItemExpanding(
            muxc::NavigationView const& sender,
            muxc::NavigationViewItemExpandingEventArgs const& args);
        void OnItemCollapsed(
            muxc::NavigationView const& sender,
            muxc::NavigationViewItemCollapsedEventArgs const& args);

    private:
        Windows::Foundation::Collections::
            IObservableVector<HierarchicalNavigationViewDataBinding::Category> m_categories;
    };
}

namespace winrt::HierarchicalNavigationViewDataBinding::factory_implementation
{
    struct MainPage : MainPageT<MainPage, implementation::MainPage>
    {
    };
}

// MainPage.cpp
#include "pch.h"
#include "MainPage.h"
#include "MainPage.g.cpp"

#include "Category.h"

namespace winrt::HierarchicalNavigationViewDataBinding::implementation
{
    MainPage::MainPage()
    {
        InitializeComponent();

        m_categories =
            winrt::single_threaded_observable_vector<HierarchicalNavigationViewDataBinding::Category>();

        auto menuItem10 = winrt::make_self<HierarchicalNavigationViewDataBinding::implementation::Category>
            (L"Menu item 10", L"Icon", nullptr);

        auto menuItem9 = winrt::make_self<HierarchicalNavigationViewDataBinding::implementation::Category>
            (L"Menu item 9", L"Icon", nullptr);
        auto menuItem8 = winrt::make_self<HierarchicalNavigationViewDataBinding::implementation::Category>
            (L"Menu item 8", L"Icon", nullptr);
        auto menuItem7Children =
            winrt::single_threaded_observable_vector<HierarchicalNavigationViewDataBinding::Category>();
        menuItem7Children.Append(*menuItem9);
        menuItem7Children.Append(*menuItem8);

        auto menuItem7 = winrt::make_self<HierarchicalNavigationViewDataBinding::implementation::Category>
            (L"Menu item 7", L"Icon", menuItem7Children);
        auto menuItem6Children =
            winrt::single_threaded_observable_vector<HierarchicalNavigationViewDataBinding::Category>();
        menuItem6Children.Append(*menuItem7);

        auto menuItem6 = winrt::make_self<HierarchicalNavigationViewDataBinding::implementation::Category>
            (L"Menu item 6", L"Icon", menuItem6Children);

        auto menuItem5 = winrt::make_self<HierarchicalNavigationViewDataBinding::implementation::Category>
            (L"Menu item 5", L"Icon", nullptr);
        auto menuItem4 = winrt::make_self<HierarchicalNavigationViewDataBinding::implementation::Category>
            (L"Menu item 4", L"Icon", nullptr);
        auto menuItem3Children =
            winrt::single_threaded_observable_vector<HierarchicalNavigationViewDataBinding::Category>();
        menuItem3Children.Append(*menuItem5);
        menuItem3Children.Append(*menuItem4);

        auto menuItem3 = winrt::make_self<HierarchicalNavigationViewDataBinding::implementation::Category>
            (L"Menu item 3", L"Icon", menuItem3Children);
        auto menuItem2Children =
            winrt::single_threaded_observable_vector<HierarchicalNavigationViewDataBinding::Category>();
        menuItem2Children.Append(*menuItem3);

        auto menuItem2 = winrt::make_self<HierarchicalNavigationViewDataBinding::implementation::Category>
            (L"Menu item 2", L"Icon", menuItem2Children);
        auto menuItem1Children =
            winrt::single_threaded_observable_vector<HierarchicalNavigationViewDataBinding::Category>();
        menuItem1Children.Append(*menuItem2);

        auto menuItem1 = winrt::make_self<HierarchicalNavigationViewDataBinding::implementation::Category>
            (L"Menu item 1", L"Icon", menuItem1Children);

        m_categories.Append(*menuItem1);
        m_categories.Append(*menuItem6);
        m_categories.Append(*menuItem10);
    }

    Windows::Foundation::Collections::IObservableVector<HierarchicalNavigationViewDataBinding::Category>
        MainPage::Categories()
    {
        return m_categories;
    }

    void MainPage::OnItemInvoked(
        muxc::NavigationView const& /* sender */,
        muxc::NavigationViewItemInvokedEventArgs const& args)
    {
        auto clickedItem = args.InvokedItem();
        auto clickedItemContainer = args.InvokedItemContainer();
    }

    void MainPage::OnItemExpanding(
        muxc::NavigationView const& /* sender */,
        muxc::NavigationViewItemExpandingEventArgs const& args)
    {
        auto nvib = args.ExpandingItemContainer();
        auto name = L"Last expanding: " + winrt::unbox_value<winrt::hstring>(nvib.Content());
        ExpandingItemLabel().Text(name);
    }

    void MainPage::OnItemCollapsed(
        muxc::NavigationView const& /* sender */,
        muxc::NavigationViewItemCollapsedEventArgs const& args)
    {
        auto nvib = args.CollapsedItemContainer();
        auto name = L"Last collapsed: " + winrt::unbox_value<winrt::hstring>(nvib.Content());
        CollapsedItemLabel().Text(name);
    }
}

Auswahl

Standardmäßig kann jedes Element untergeordnete Elemente enthalten, aufgerufen oder ausgewählt werden.

Wenn Sie Benutzern eine hierarchische Struktur von Navigationsoptionen bereitstellen, können Sie festlegen, dass übergeordnete Elemente nicht auswählbar sind, z. B. wenn Ihre App über keine diesem übergeordneten Element zugeordnete Zielseite verfügt. Wenn Ihre übergeordneten Elemente auswählbar sind, empfiehlt es sich, die Anzeigemodi „Left-Expanded“ oder „Top“ zu verwenden. Der Modus „LeftCompact“ veranlasst den Benutzer, zum übergeordneten Element zu navigieren, um bei jedem Aufruf die untergeordnete Teilstruktur zu öffnen.

Die Auswahlindikatoren ausgewählter Elemente werden im Modus „Left“ entlang des linken Rands bzw. im Modus „Top“ entlang des unteren Rands gezeichnet. Unten sehen Sie NavigationViews in den Modi „Left“ und „Top“ bei Auswahl eines übergeordneten Elements.

NavigationView im Modus „Left“ mit ausgewähltem übergeordneten Element

NavigationView im Modus „Top“ mit ausgewähltem übergeordneten Element

Das ausgewählte Element ist möglicherweise nicht immer sichtbar. Wenn ein untergeordnetes Element in einer reduzierten/nicht erweiterten Unterstruktur ausgewählt ist, wird der erste sichtbare Vorgänger als ausgewählt angezeigt. Der Auswahlindikator wechselt zurück zum ausgewählten Element, wenn/sobald die Unterstruktur erweitert wird.

Beispiel: Angenommen, in der Abbildung oben wird das Kalenderelement vom Benutzer ausgewählt, und der Benutzer reduziert dann die Unterstruktur. In diesem Fall wird der Auswahlindikator unterhalb des Kontoelements angezeigt, da „Konto“ der erste sichtbare Vorgänger von „Kalender“ ist. Der Auswahlindikator wechselt zurück zum Kalenderelement, wenn der Benutzer die Unterstruktur wieder erweitert.

In der gesamten NavigationView wird nicht mehr als ein Auswahlindikator angezeigt.

Durch Klicken auf die Pfeile von NavigationViewItems in den Modi „Top“ und „Left“ wird die Unterstruktur erweitert oder reduziert. Durch Klicken oder Tippen an anderer Stelle von NavigationViewItem wird das ItemInvoked-Ereignis ausgelöst und zudem die Teilstruktur reduziert oder erweitert.

Um zu verhindern, dass ein Element beim Aufruf den Auswahlindikator anzeigt, legen Sie dessen SelectsOnInvoked-Eigenschaft auf „False“ fest, wie unten dargestellt:

<Page ...>
    <Page.Resources>
        <DataTemplate x:Key="NavigationViewMenuItem" x:DataType="local:Category">
            <NavigationViewItem Content="{x:Bind Name}"
            MenuItemsSource="{x:Bind Children}"
            SelectsOnInvoked="{x:Bind IsLeaf}"/>
        </DataTemplate>
    </Page.Resources>

    <Grid>
        <NavigationView x:Name="navview"
    MenuItemsSource="{x:Bind Categories, Mode=OneWay}"
    MenuItemTemplate="{StaticResource NavigationViewMenuItem}">
        </NavigationView>
    </Grid>
</Page>
public class Category
{
    public String Name { get; set; }
    public String CategoryIcon { get; set; }
    public ObservableCollection<Category> Children { get; set; }
    public bool IsLeaf { get; set; }
}

public sealed partial class HierarchicalNavigationViewDataBinding : Page
{
    public HierarchicalNavigationViewDataBinding()
    {
        this.InitializeComponent();
    }

    public ObservableCollection<Category> Categories = new ObservableCollection<Category>()
    {
        new Category(){
            Name = "Menu item 1",
            CategoryIcon = "Icon",
            Children = new ObservableCollection<Category>() {
                new Category(){
                    Name = "Menu item 2",
                    CategoryIcon = "Icon",
                    Children = new ObservableCollection<Category>() {
                        new Category() {
                            Name  = "Menu item 3",
                            CategoryIcon = "Icon",
                            Children = new ObservableCollection<Category>() {
                                new Category() { Name  = "Menu item 4", CategoryIcon = "Icon", IsLeaf = true },
                                new Category() { Name  = "Menu item 5", CategoryIcon = "Icon", IsLeaf = true }
                            }
                        }
                    }
                }
            }
        },
        new Category(){
            Name = "Menu item 6",
            CategoryIcon = "Icon",
            Children = new ObservableCollection<Category>() {
                new Category(){
                    Name = "Menu item 7",
                    CategoryIcon = "Icon",
                    Children = new ObservableCollection<Category>() {
                        new Category() { Name  = "Menu item 8", CategoryIcon = "Icon", IsLeaf = true },
                        new Category() { Name  = "Menu item 9", CategoryIcon = "Icon", IsLeaf = true }
                    }
                }
            }
        },
        new Category(){ Name = "Menu item 10", CategoryIcon = "Icon", IsLeaf = true }
    };
}
// Category.idl
namespace HierarchicalNavigationViewDataBinding
{
    runtimeclass Category
    {
        ...
        Boolean IsLeaf;
    }
}

// Category.h
...
struct Category : CategoryT<Category>
{
    ...
    Category(winrt::hstring name,
        winrt::hstring categoryIcon,
        Windows::Foundation::Collections::IObservableVector<HierarchicalNavigationViewDataBinding::Category> children,
        bool isleaf = false);
    ...
    bool IsLeaf();
    void IsLeaf(bool value);

private:
    ...
    bool m_isleaf;
};

// Category.cpp
...
Category::Category(winrt::hstring name,
    winrt::hstring categoryIcon,
    Windows::Foundation::Collections::IObservableVector<HierarchicalNavigationViewDataBinding::Category> children,
    bool isleaf) : m_name(name), m_categoryIcon(categoryIcon), m_children(children), m_isleaf(isleaf) {}
...
bool Category::IsLeaf()
{
    return m_isleaf;
}

void Category::IsLeaf(bool value)
{
    m_isleaf = value;
}

// MainPage.h and MainPage.cpp
// Delete OnItemInvoked, OnItemExpanding, and OnItemCollapsed.

// MainPage.cpp
...
MainPage::MainPage()
{
    InitializeComponent();

    m_categories = winrt::single_threaded_observable_vector<HierarchicalNavigationViewDataBinding::Category>();

    auto menuItem10 =
        winrt::make_self<HierarchicalNavigationViewDataBinding::implementation::Category>
        (L"Menu item 10", L"Icon", nullptr, true);

    auto menuItem9 =
        winrt::make_self<HierarchicalNavigationViewDataBinding::implementation::Category>
        (L"Menu item 9", L"Icon", nullptr, true);
    auto menuItem8 =
        winrt::make_self<HierarchicalNavigationViewDataBinding::implementation::Category>
        (L"Menu item 8", L"Icon", nullptr, true);
    auto menuItem7Children =
        winrt::single_threaded_observable_vector<HierarchicalNavigationViewDataBinding::Category>();
    menuItem7Children.Append(*menuItem9);
    menuItem7Children.Append(*menuItem8);

    auto menuItem7 =
        winrt::make_self<HierarchicalNavigationViewDataBinding::implementation::Category>
        (L"Menu item 7", L"Icon", menuItem7Children);
    auto menuItem6Children =
        winrt::single_threaded_observable_vector<HierarchicalNavigationViewDataBinding::Category>();
    menuItem6Children.Append(*menuItem7);

    auto menuItem6 =
        winrt::make_self<HierarchicalNavigationViewDataBinding::implementation::Category>
        (L"Menu item 6", L"Icon", menuItem6Children);

    auto menuItem5 =
        winrt::make_self<HierarchicalNavigationViewDataBinding::implementation::Category>
        (L"Menu item 5", L"Icon", nullptr, true);
    auto menuItem4 =
        winrt::make_self<HierarchicalNavigationViewDataBinding::implementation::Category>
        (L"Menu item 4", L"Icon", nullptr, true);
    auto menuItem3Children =
        winrt::single_threaded_observable_vector<HierarchicalNavigationViewDataBinding::Category>();
    menuItem3Children.Append(*menuItem5);
    menuItem3Children.Append(*menuItem4);

    auto menuItem3 =
        winrt::make_self<HierarchicalNavigationViewDataBinding::implementation::Category>
        (L"Menu item 3", L"Icon", menuItem3Children);
    auto menuItem2Children =
        winrt::single_threaded_observable_vector<HierarchicalNavigationViewDataBinding::Category>();
    menuItem2Children.Append(*menuItem3);

    auto menuItem2 =
        winrt::make_self<HierarchicalNavigationViewDataBinding::implementation::Category>
        (L"Menu item 2", L"Icon", menuItem2Children);
    auto menuItem1Children =
        winrt::single_threaded_observable_vector<HierarchicalNavigationViewDataBinding::Category>();
    menuItem1Children.Append(*menuItem2);

    auto menuItem1 =
        winrt::make_self<HierarchicalNavigationViewDataBinding::implementation::Category>
        (L"Menu item 1", L"Icon", menuItem1Children);

    m_categories.Append(*menuItem1);
    m_categories.Append(*menuItem6);
    m_categories.Append(*menuItem10);
}
...

Tastaturunterstützung innerhalb einer hierarchischen NavigationView

Benutzer können den Fokus in „NavigationView“ mithilfe ihrer Tastatur verschieben. Die Pfeiltasten machen innerhalb des Bereichs die „innere Navigation“ verfügbar und folgen den in der Strukturansicht bereitgestellten Interaktionen. Die Tastenaktionen ändern sich während der Navigation in der NavigationView oder dem zugehörigen Flyoutmenü, das in den Modi „Top“ und „Left-compact“ von HierarchicalNavigationView angezeigt wird. Im folgenden finden Sie die speziellen Aktionen, die jede Taste in einer hierarchischen NavigationView ausführen kann:

Schlüssel Im Modus „Left“ Im Modus „Top“ Im Flyout
Nach oben Verschiebt den Fokus auf das Element direkt oberhalb des Elements, das aktuell den Fokus hält. Führt keine Aktion aus. Verschiebt den Fokus auf das Element direkt oberhalb des Elements, das aktuell den Fokus hält.
Nach unten Verschiebt den Fokus auf das Element direkt unterhalb des Elements, das aktuell den Fokus hält.* Führt keine Aktion aus. Verschiebt den Fokus auf das Element direkt unterhalb des Elements, das aktuell den Fokus hält.*
Rechts Führt keine Aktion aus. Verschiebt den Fokus auf das Element direkt rechts von dem Element, das aktuell den Fokus hält. Führt keine Aktion aus.
Links Führt keine Aktion aus. Verschiebt den Fokus auf das Element direkt links von dem Element, das aktuell den Fokus hält. Führt keine Aktion aus.
LEERTASTE/EINGABETASTE Wenn das Element untergeordnete Elemente aufweist, wird das Element erweitert oder reduziert, und der Fokus wird nicht geändert. Wenn das Element über untergeordnete Elemente verfügt, werden die untergeordneten Elemente in ein Flyout erweitert, und der Fokus wird auf das erste Element im Flyout gesetzt. Ruft ein Element auf oder wählt ein Element aus und schließt das Flyout.
ESC Führt keine Aktion aus. Führt keine Aktion aus. Schließt das Flyout.

Die LEERTASTE oder die EINGABETASTE bewirkt immer, dass ein Element aufgerufen bzw. ausgewählt wird.

*Beachten Sie, dass die Elemente nicht visuell aneinander angrenzend angeordnet sein müssen. Der Fokus wird vom letzten Element in der Liste des Bereichs auf das Einstellungselement verschoben.

Bereichshintergründe

Standardmäßig wird je nach Anzeigemodus im NavigationView-Bereich ein anderer Hintergrund verwendet:

  • Der Bereich ist grau, wenn er nach links erweitert wird (neben dem Inhalt, im Modus „Links“).
  • Für den Bereich wird In-App-Acryl verwendet, wenn er als Überlagerung auf dem Inhalt geöffnet wird (im Modus „Oben“, „Minimal“ oder „Kompakt“).

Zum Ändern des Bereichshintergrunds kannst du die XAML-Designressourcen außer Kraft setzen, die in den einzelnen Modi zum Rendern des Hintergrunds verwendet werden. (Dieses Verfahren wird anstelle einer einzelnen PaneBackground-Eigenschaft genutzt, um unterschiedliche Hintergründe für unterschiedliche Anzeigemodi zu unterstützen.)

In dieser Tabelle ist angegeben, welche Designressource in den unterschiedlichen Anzeigemodi verwendet wird.

Anzeigemodus Designressource
Links NavigationViewExpandedPaneBackground
LeftCompact
LeftMinimal
NavigationViewDefaultPaneBackground
Oben NavigationViewTopPaneBackground

In diesem Beispiel wird veranschaulicht, wie du die Designressourcen in „App.xaml“ außer Kraft setzt. Beim Außerkraftsetzen der Designressourcen solltest du immer mindestens die Ressourcenwörterbücher „Default“ und „HighContrast“ sowie je nach Bedarf Wörterbücher für Ressourcen vom Typ „Light“ oder „Dark“ bereitstellen. Weitere Informationen findest du unter ResourceDictionary.ThemeDictionaries.

Wichtig

Dieser Code veranschaulicht, wie Sie die WinUI 2-Version von AcrylicBrush verwenden können. Wenn du stattdessen die Plattformversion von „AcrylicBrush“ nutzt, muss die Mindestversion für dein App-Projekt „SDK 16299“ oder höher lauten. Entferne zum Verwenden der Plattformversion alle Verweise auf muxm:.

<Application ... xmlns:muxm="using:Microsoft.UI.Xaml.Media" ...>
    <Application.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <XamlControlsResources xmlns="using:Microsoft.UI.Xaml.Controls"/>
                <ResourceDictionary>
                    <ResourceDictionary.ThemeDictionaries>
                        <ResourceDictionary x:Key="Default">
                            <!-- The "Default" theme dictionary is used unless a specific
                                 light, dark, or high contrast dictionary is provided. These
                                 resources should be tested with both the light and dark themes,
                                 and specific light or dark resources provided as needed. -->
                            <muxm:AcrylicBrush x:Key="NavigationViewDefaultPaneBackground"
                                   BackgroundSource="Backdrop"
                                   TintColor="LightSlateGray"
                                   TintOpacity=".6"/>
                            <muxm:AcrylicBrush x:Key="NavigationViewTopPaneBackground"
                                   BackgroundSource="Backdrop"
                                   TintColor="{ThemeResource SystemAccentColor}"
                                   TintOpacity=".6"/>
                            <LinearGradientBrush x:Key="NavigationViewExpandedPaneBackground"
                                     StartPoint="0.5,0" EndPoint="0.5,1">
                                <GradientStop Color="LightSlateGray" Offset="0.0" />
                                <GradientStop Color="White" Offset="1.0" />
                            </LinearGradientBrush>
                        </ResourceDictionary>
                        <ResourceDictionary x:Key="HighContrast">
                            <!-- Always include a "HighContrast" dictionary when you override
                                 theme resources. This empty dictionary ensures that the
                                 default high contrast resources are used when the user
                                 turns on high contrast mode. -->
                        </ResourceDictionary>
                    </ResourceDictionary.ThemeDictionaries>
                </ResourceDictionary>
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Application.Resources>
</Application>

Leerraum oben

Die IsTitleBarAutoPaddingEnabled-Eigenschaft erfordert WinUI 2.2 oder höher.

Einige Apps passen die Titelleiste ihres Fensters an und erweitern so den App-Inhalt auf den Bereich der Titelleiste. Wenn NavigationView das Stammelement in Apps ist, die ihren Inhalt mithilfe der ExtendViewIntoTitleBar-API in die Titelleiste erweitern, passt das Steuerelement die Position seiner interaktiven Elemente automatisch an, um eine Überlappung mit dem ziehbaren Bereich zu vermeiden.

Eine App, die ihren Inhalt in die Titelleiste erweitert

Wenn Ihre App den ziehbaren Bereich durch Aufrufen der Window.SetTitleBar-Methode angibt und Sie die Schaltflächen „Zurück“ und „Menü“ lieber oben im App-Fenster anordnen möchten, legen Sie IsTitleBarAutoPaddingEnabled auf false fest.

App, die ihren Inhalt in die Titelleiste erweitert, ohne Innenabstand

<muxc:NavigationView x:Name="NavView" IsTitleBarAutoPaddingEnabled="False">

Hinweise

Um die Position des Kopfzeilenbereichs von NavigationView genauer anzupassen, überschreibe die XAML-Themenressource NavigationViewHeaderMargin – z. B. in den Ressourcen für die Seite.

<Page.Resources>
    <Thickness x:Key="NavigationViewHeaderMargin">12,0</Thickness>
</Page.Resources>

Diese Themenressource ändert den Rand um NavigationView.Header.