瀏覽檢視Navigation view

NavigationView 控制項提供您的應用程式最上層瀏覽。The NavigationView control provides top-level navigation for your app. 其可配合各種不同的螢幕大小,並且同時支援「頂端」和「左側」的瀏覽樣式。It adapts to a variety of screen sizes and supports both top and left navigation styles.

頂端瀏覽top navigation
瀏覽檢視支援頂端和左側瀏覽窗格或功能表Navigation view supports both top and left navigation pane or menu

取得 Windows UI 程式庫Get the Windows UI Library

WinUI 標誌 NavigationView 控制項包含在 Windows UI 程式庫中,該程式庫是 NuGet 套件,其中包含適用於 Windows 應用程式的新控制項和 UI 功能。The NavigationView control is included as part of the Windows UI Library, a NuGet package that contains new controls and UI features for Windows apps. 如需詳細資訊 (包括安裝指示),請參閱 Windows UI 程式庫概觀For more info, including installation instructions, see the Windows UI Library overview.

平台 APIWindows.UI.Xaml.Controls.NavigationView 類別Platform APIs: Windows.UI.Xaml.Controls.NavigationView class

Windows UI 程式庫 APIMicrosoft.UI.Xaml.Controls.NavigationView 類別Windows UI Library APIs: Microsoft.UI.Xaml.Controls.NavigationView class

NavigationView 的一些功能 (例如「頂端」和「階層式」瀏覽) 需要 Windows 10 版本 1809年 (SDK 17763) 或更新版本,或 Windows UI 程式庫Some features of NavigationView, such as top and hierarchical navigation, require Windows 10, version 1809 (SDK 17763) or later, or the Windows UI Library.

這是正確的控制項嗎?Is this the right control?

NavigationView 是調適型瀏覽控制項,適用於:NavigationView is an adaptive navigation control that works well for:

  • 提供跨應用程式一致的瀏覽體驗。Providing a consistent navigational experience throughout your app.
  • 保留較小視窗的螢幕實際可用空間。Preserving screen real estate on smaller windows.
  • 安排對於許多瀏覽類別的存取。Organizing access to many navigation categories.

關於其他瀏覽模式,請參閱瀏覽設計基本概念For other navigation patterns, see Navigation design basics.

範例Examples

XAML 控制項庫XAML Controls Gallery
XAML controls gallery

如果您已安裝 XAML 控制項庫應用程式,請按一下這裡開啟應用程式並查看 NavigationView 運作情形If you have the XAML Controls Gallery app installed, click here to open the app and see the NavigationView in action.

顯示模式Display modes

PaneDisplayMode 屬性需要 Windows 10 1809 版 (SDK 17763) 或更新版本,或 Windows UI 程式庫 (英文)。The PaneDisplayMode property requires Windows 10, version 1809 (SDK 17763) or later, or the Windows UI Library.

您可以使用 PaneDisplayMode 屬性來設定 NavigationView 的不同瀏覽樣式或顯示模式。You can use the PaneDisplayMode property to configure different navigation styles, or display modes, for the NavigationView.

頁首Top

窗格位於內容上方。The pane is positioned above the content.
PaneDisplayMode="Top"

頂端瀏覽的範例

對於下列情況建議_頂端_瀏覽:We recommend top navigation when:

  • 您有 5 個以內同樣重要的最上層瀏覽類別,以及其他任何最上層瀏覽類型,因此下拉式溢位功能表被視為較不重要。You have 5 or fewer top-level navigation categories that are equally important, and any additional top-level navigation categories that end up in the dropdown overflow menu are considered less important.
  • 您需要在螢幕上顯示所有的瀏覽選項。You need to show all navigation options on screen.
  • 您想要您的應用程式內容有更多空間。You want more space for your app content.
  • 圖示無法清楚地描述您的應用程式瀏覽類別。Icons cannot clearly describe your app's navigation categories.

LeftLeft

窗格會展開,並位於內容的左側。The pane is expanded and positioned to the left of the content.
PaneDisplayMode="Left"

展開左側瀏覽窗格的範例

對於下列情況建議_左側_瀏覽:We recommend left navigation when:

  • 有 5 個至 10 個同樣重要的最上層瀏覽類別。You have 5-10 equally important top-level navigation categories.
  • 您想要瀏覽類別相當顯著,而且其他應用程式內容的空間較少。You want navigation categories to be very prominent, with less space for other app content.

LeftCompactLeftCompact

窗格只會在開啟時顯示圖示,並位於內容的左側。The pane shows only icons until opened and is positioned to the left of the content.
PaneDisplayMode="LeftCompact"

精簡左側瀏覽窗格的範例

LeftMinimalLeftMinimal

只有在窗格開啟時,功能表按鈕才會顯示。Only the menu button is shown until the pane is opened. 這開啟時位於內容的左側。When opened, it's positioned to the left of the content.
PaneDisplayMode="LeftMinimal"

基本左側瀏覽窗格的範例

自動Auto

PaneDisplayMode 預設設定為 [自動]。在自動模式中,瀏覽檢視會切換為 LeftMinimal (視窗變窄時)、LeftCompact 和 Left (視窗變寬時)。By default, PaneDisplayMode is set to Auto. In Auto mode, the navigation view adapts between LeftMinimal when the window is narrow, to LeftCompact, and then Left as the window gets wider. 如需詳細資訊,請參閱調適型行為一節。For more info, see the adaptive behavior section.

左側瀏覽預設調適型行為Left navigation default adaptive behavior
瀏覽檢視預設調適型行為Navigation view default adaptive behavior

結構Anatomy

這些圖片顯示對於_頂端_或_左側_瀏覽設定時窗格、頁首和控制項內容區域的配置。These images show the layout of the pane, header, and content areas of the control when configured for top or left navigation.

頂端瀏覽檢視配置Top navigation view layout
頂端瀏覽配置Top navigation layout

左側瀏覽檢視配置Left navigation view layout
左側瀏覽配置Left navigation layout

窗格Pane

您可以使用 PaneDisplayMode 屬性,將窗格放置於內容上方或內容左側。You can use the PaneDisplayMode property to position the pane above the content or to the left of the content.

NavigationView 窗格可以包含:The NavigationView pane can contain:

左窗格也包含:The left pane also contains:

  • 切換開啟和關閉窗格的功能表按鈕。A menu button to toggle the pane opened and closed. 在較大的應用程式視窗上,當窗格開啟時,您可以選擇使用 IsPaneToggleButtonVisible 屬性隱藏此按鈕。On larger app windows when the pane is open, you may choose to hide this button using the IsPaneToggleButtonVisible property.

瀏覽檢視有放置在窗格左上角的返回按鈕。The navigation view has a back button that is placed in the top left-hand corner of the pane. 不過,這會自動處理向後瀏覽,並將內容新增至返回堆疊。However, it does not automatically handle backwards navigation and add content to the back stack. 若要啟用向後瀏覽,請參閱向後瀏覽一節。To enable backwards navigation, see the backwards navigation section.

以下是頂端和左側窗格位置的詳細的窗格結構。Here is the detailed pane anatomy for the top and left pane positions.

頂端瀏覽窗格Top navigation pane

瀏覽檢視頂端窗格結構

  1. 標頭Headers
  2. 瀏覽項目Navigation items
  3. 分隔符號Separators
  4. AutoSuggestBox (選用)AutoSuggestBox (optional)
  5. 設定按鈕 (選用)Settings button (optional)

左側瀏覽窗格Left navigation pane

瀏覽檢視左側窗格結構

  1. 功能表按鈕Menu button
  2. 瀏覽項目Navigation items
  3. 分隔符號Separators
  4. 標頭Headers
  5. AutoSuggestBox (選用)AutoSuggestBox (optional)
  6. 設定按鈕 (選用)Settings button (optional)

您可以將自由格式內容新增至 PaneFooter 屬性,在窗格頁尾中放置自由格式內容。You can place free-form content in the pane's footer by adding it to the PaneFooter property.

窗格頁尾頂端瀏覽Pane footer top nav
頂端窗格頁尾Top pane footer

窗格頁尾左側瀏覽Pane footer left nav
左側窗格頁尾Left pane footer

窗格標題和頁首Pane title and header

您也可以設定 PaneTitle 屬性,在窗格標頭區域中放置文字內容。You can place text content in the pane header area by setting the PaneTitle property. 其會使用字串,並顯示功能表按鈕旁邊的文字。It takes a string and shows the text next to the menu button.

若要新增非文字內容,例如圖片或標誌,您可以將任何元素新增至 PaneHeader 屬性,以便置於窗格的頁首。To add non-text content, such as an image or logo, you can place any element in the pane's header by adding it to the PaneHeader property.

如果已設定 PaneTitle 和 PaneHeader,內容會在功能表按鈕旁邊水平堆疊,而且 PaneTitle 最接近功能表按鈕。If both PaneTitle and PaneHeader are set, the content is stacked horizontally next to the menu button, with the PaneTitle closest to the menu button.

窗格頁首頂端瀏覽Pane header top nav
頂端窗格頁首Top pane header

窗格頁首左側瀏覽Pane header left nav
左側窗格頁首Left pane header

窗格內容Pane content

您可以將自由格式內容新增至 PaneCustomContent 屬性,在窗格中放置自由格式內容。You can place free-form content in the pane by adding it to the PaneCustomContent property.

窗格自訂內容頂端瀏覽Pane custom content top nav
頂端窗格自訂內容Top pane custom content

窗格自訂內容左側瀏覽Pane custom content left nav
左側窗格自訂內容Left pane custom content

您可以設定 Header 屬性新增頁面標題。You can add a page title by setting the Header property.

瀏覽檢視頁首區域的範例Example of navigation view header area
瀏覽檢視頁首Navigation view header

頁首區域與左側窗格位置的導覽按鈕垂直對齊,而且導覽按鈕在左側窗格位置,並位於頂端窗格位置中的窗格下方。The header area is vertically aligned with the navigation button in the left pane position, and lies below the pane in the top pane position. 這有 52 px 的固定高度。It has a fixed height of 52 px. 其目的是保留所選瀏覽類別的頁面標題。Its purpose is to hold the page title of the selected nav category. 頁首停駐在頁面頂端,並且做為內容區域的捲動裁剪點。The header is docked to the top of the page and acts as a scroll clipping point for the content area.

頁首始終顯示,NavigationView 為基本顯示模式。The header is visible any time the NavigationView is in Minimal display mode. 您可以選擇在其他用於較大視窗寬度的模式下隱藏頁首。You may choose to hide the header in other modes, which are used on larger window widths. 若要隱藏頁首,請將 AlwaysShowHeader 屬性設定為 falseTo hide the header, set the AlwaysShowHeader property to false.

內容Content

瀏覽檢視內容區域的範例Example of navigation view content area
瀏覽檢視內容Navigation view content

內容區域是顯示所選瀏覽類別大部分資訊的位置。The content area is where most of the information for the selected nav category is displayed.

當 NavigationView 處於 [基本] 模式時,建議您在內容區域使用 12px 邊界,若為其他模式則使用 24px 邊界。We recommend 12px margins for your content area when NavigationView is in Minimal mode and 24px margins otherwise.

調適性行為Adaptive behavior

瀏覽檢視預設會根據其可用的螢幕空間量自動變更顯示模式。By default, the navigation view automatically changes its display mode based on the amount of screen space available to it. CompactModeThresholdWidthExpandedModeThresholdWidth 屬性會指定顯示模式變更的中斷點。The CompactModeThresholdWidth and ExpandedModeThresholdWidth properties specify the breakpoints at which the display mode changes. 您可以修改這些值,以自訂調適性顯示模式行為。You can modify these values to customize the adaptive display mode behavior.

DefaultDefault

PaneDisplayMode 是設定為 Auto 的預設值,調適性行為會顯示:When PaneDisplayMode is set to its default value of Auto, the adaptive behavior is to show:

  • 大型視窗寬度 (1008px 或更大) 的展開左側窗格。An expanded left pane on large window widths (1008px or greater).
  • 中等視窗寬度 (641px 至 1007px) 的左側僅圖示瀏覽窗格 (LeftCompact)。A left, icon-only, nav pane (LeftCompact) on medium window widths (641px to 1007px).
  • 小型視窗寬度 (640px 或更小) 的僅功能表按鈕 (LeftMinimal)。Only a menu button (LeftMinimal) on small window widths (640px or less).

如需調適性行為視窗大小的詳細資訊,請參閱螢幕大小和中斷點For more information about window sizes for adaptive behavior, see Screen sizes and breakpoints.

左側瀏覽預設調適型行為Left navigation default adaptive behavior
瀏覽檢視預設調適型行為Navigation view default adaptive behavior

基本Minimal

第二個常見的調適性模式是使用大型視窗寬度的展開左側窗格,以及中等和小型視窗寬度的功能表按鈕。A second common adaptive pattern is to use an expanded left pane on large window widths, and only a menu button on both medium and small window widths.

我們建議在下列情況時使用:We recommend this when:

  • 您想要較小視窗寬度的應用程式內容有更多空間。You want more space for app content on smaller window widths.
  • 您的瀏覽類別無法以圖示清楚表示。Your navigation categories cannot be clearly represented with icons.

左側瀏覽基本調適型行為Left navigation minimal adaptive behavior
瀏覽檢視「基本」調適型行為Navigation view "minimal" adaptive behavior

若要設定此行為,請將 CompactModeThresholdWidth 設訂為想要窗格摺疊的寬度。To configure this behavior, set CompactModeThresholdWidth to the width at which you want the pane to collapse. 在其中,這是從預設的 640 變更為 1007。Here, it's changed from the default of 640 to 1007. 您也應該設定 ExpandedModeThresholdWidth 以確保值不衝突。You should also set ExpandedModeThresholdWidth to ensure the values don't conflict.

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

精簡Compact

第三個常見的調適性模式是使用大型視窗寬度的展開左側窗格,以及中等和小型視窗寬度的 LeftCompact 僅圖示瀏覽窗格。A third common adaptive pattern is to use an expanded left pane on large window widths, and a LeftCompact, icon-only, nav pane on both medium and small window widths.

我們建議在下列情況時使用:We recommend this when:

  • 務必在螢幕上顯示所有瀏覽選項。It is important to always show all navigation options on screen.
  • 您的瀏覽類別能夠以圖示清楚表示。Your navigation categories can be clearly represented with icons.

左側瀏覽精簡調適型行為Left navigation compact adaptive behavior
瀏覽檢視「精簡」調適型行為Navigation view "compact" adaptive behavior

若要設定此行為,請將 CompactModeThresholdWidth 設定為 0。To configure this behavior, set CompactModeThresholdWidth to 0.

<NavigationView CompactModeThresholdWidth="0"/>

無調適性行為No adaptive behavior

若要停用調適性行為,請將 PaneDisplayMode 設定為 Auto 以外的值。在其中,這是設定為 LeftMinimal,因此,無論視窗的寬度為何,功能表按鈕都會顯示。To disable the automatic adaptive behavior, set PaneDisplayMode to a value other than Auto. Here, it's set to LeftMinimal, so only the menu button is shown regardless of the window width.

左側瀏覽無調適型行為Left navigation no adaptive behavior
PaneDisplayMode 設定為 LeftMinimal 的瀏覽檢視Navigation view with PaneDisplayMode set to LeftMinimal

<NavigationView PaneDisplayMode="LeftMinimal" />

如先前在_顯示模式_小節中所述,您可以設定窗格始終在頂端、始終展開、始終精簡,或始終基本。As described previously in the Display modes section, you can set the pane to be always on top, always expanded, always compact, or always minimal. 您也可以自己的應用程式程式碼中自行管理顯示模式。You can also manage the display modes yourself in your app code. 下一節將顯示這個的範例。An example of this is shown in the next section.

頂端至左側瀏覽Top to left navigation

您在應用程式中使用頂端瀏覽時,瀏覽項目會在視窗寬度減少時摺疊為溢位功能表。When you use top navigation in your app, navigation items collapse into an overflow menu as the window width decreases. 應用程式視窗變窄時,將 PaneDisplayMode 從 Top 切換為 LeftMinimal 瀏覽,而不是將所有項目摺疊為溢位功能表,可提供較佳的使用者體驗。When your app window is narrow, it can provide a better user experience to switch the PaneDisplayMode from Top to LeftMinimal navigation, rather than letting all the items collapse into the overflow menu.

在下列情況時,建議對於大型視窗大小使用頂端瀏覽,並對於小型視窗大小使用左側瀏覽:We recommend using top navigation on large window sizes and left navigation on small window sizes when:

  • 有一組同樣重要的最上層瀏覽類別需要一起顯示,以便在此組中的一個類別無法在畫面上完整顯示時,可以摺疊為左側瀏覽來呈現同等重要性。You have a set of equally important top-level navigation categories to be displayed together, such that if one category in this set doesn't fit on screen, you collapse to left navigation to give them equal importance.
  • 您想要對於小型視窗大小盡可能保留更多內容空間。You wish to preserve as much content space as possible in small window sizes.

此範例顯示如何使用 VisualStateManagerAdaptiveTrigger.MinWindowWidth 切換頂端和 LeftMinimal 瀏覽屬性。This example shows how to use a VisualStateManager and AdaptiveTrigger.MinWindowWidth property to switch between Top and LeftMinimal navigation.

頂端或左側調適性行為 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>

提示

您使用 AdaptiveTrigger.MinWindowWidth 時,在視窗超出指定最小寬度的情況下,會觸發視覺狀態。When you use AdaptiveTrigger.MinWindowWidth, the visual state is triggered when the window is wider than the specified minimum width. 這表示預設 XAML 定義窄視窗,而且 VisualState 定義視窗變寬時套用的修改。This means the default XAML defines the narrow window, and the VisualState defines the modifications that are applied when the window gets wider. 瀏覽檢視的預設 PaneDisplayMode 為 Auto,因此,視窗寬度小於或等於 CompactModeThresholdWidth 時,會使用 LeftMinimal 瀏覽。The default PaneDisplayMode for the navigation view is Auto, so when the window width is less than or equal to CompactModeThresholdWidth, LeftMinimal navigation is used. 視窗變寬時,VisualState 會覆寫預設值,並使用頂端瀏覽。When the window gets wider, the VisualState overrides the default, and Top navigation is used.

瀏覽檢視不會自動執行任何瀏覽工作。The navigation view doesn't perform any navigation tasks automatically. 使用者點選瀏覽項目時,瀏覽檢視會將該項目顯示為已選取,並引發 ItemInvoked 事件。When the user taps on a navigation item, the navigation view shows that item as selected and raises an ItemInvoked event. 如果點選的動作導致不斷選取到某個新項目,也會引發 SelectionChanged 事件。If the tap results in a new item being selected, a SelectionChanged event is also raised.

您可以處理任何一個事件來執行與要求的瀏覽相關的工作。You can handle either event to perform tasks related to the requested navigation. 您應該處理哪一個取決於您的應用程式所需的行為。Which one you should handle depends on the behavior you want for your app. 一般而言,您會瀏覽至要求的頁面,並更新瀏覽檢視頁首,以回應這些事件。Typically, you navigate to the requested page and update the navigation view header in response to these events.

只要使用者點選瀏覽項目,即使是已選取的瀏覽項目,都會引發 ItemInvokedItemInvoked is raised any time the user taps a navigation item, even if it's already selected. (也可以使用滑鼠、鍵盤或其他輸入,透過對等的動作叫用項目。(The item can also be invoked with an equivalent action using mouse, keyboard, or other input. 如需詳細資訊,請參閱輸入和互動。)如果您在 ItemInvoked 處理常式中瀏覽,預設將重新載入頁面,而且重複的項目將新增至瀏覽堆疊。For more info, see Input and interactions.) If you navigate in the ItemInvoked handler, by default, the page will be reloaded, and a duplicate entry is added to the navigation stack. 如果您在叫用項目時瀏覽,您應該不允許重新載入頁面,或確定頁面重新載入時並未在瀏覽 backstack 中建立重複項目。If you navigate when an item is invoked, you should disallow reloading the page, or ensure that a duplicate entry is not created in the navigation backstack when the page is reloaded. (參考程式碼範例。)(See code examples.)

SelectionChanged 可由使用者叫用目前未選取的項目來引發,也可透過程式設計方式變更選取的項目來引發。SelectionChanged can be raised by a user invoking an item that isn't currently selected, or by programmatically changing the selected item. 如果由於使用者叫用項目而發生選取變更,會先發生 ItemInvoked 事件。If the selection change occurs because a user invoked an item, the ItemInvoked event occurs first. 如果以程式設計方式進行選取變更,不會引發 ItemInvoked。If the selection change is programmatic, ItemInvoked is not raised.

向後瀏覽Backwards navigation

NavigationView 有內建的返回按鈕;但是,和向前瀏覽一樣,這不會自動執行向後瀏覽。NavigationView has a built-in back button; but, as with forward navigation, it doesn't perform backwards navigation automatically. 使用者點選返回按鈕時,會引發 BackRequested 事件。When the user taps the back button, the BackRequested event is raised. 您可以處理這個事件來執行向後瀏覽。You handle this event to perform backwards navigation. 如需詳細資訊和程式碼範例,請參閱瀏覽歷程記錄和向後瀏覽For more info and code examples, see Navigation history and backwards navigation.

在基本或精簡模式中,瀏覽檢視窗格是以飛出視窗開啟。In Minimal or Compact mode, the navigation view Pane is open as a flyout. 在此情況下,按一下返回按鈕會關閉窗格,並引發 PaneClosing 事件。In this case, clicking the back button will close the Pane and raise the PaneClosing event instead.

您可以設定這些屬性來隱藏或停用返回按鈕:You can hide or disable the back button by setting these properties:

  • IsBackButtonVisible:用來顯示和隱藏返回按鈕。IsBackButtonVisible: use to show and hide the back button. 這個屬性會使用 NavigationViewBackButtonVisible列舉型別的值,並且預設設定為 AutoThis property takes a value of the NavigationViewBackButtonVisible enumeration, and is set to Auto by default. 按鈕摺疊時,不會在配置中保留按鈕的空間。When the button is collapsed, no space is reserved for it in the layout.
  • IsBackEnabled:用來啟用或停用返回按鈕。IsBackEnabled: use to enable or disable the back button. 您可以利用資料繫結將此屬性繫結至瀏覽畫面的 CanGoBack 屬性。You can data bind this property to the CanGoBack property of your navigation frame. 如果 IsBackEnabledfalse,不會引發 BackRequestedBackRequested is not raised if IsBackEnabled is false.

左側瀏覽窗格中的瀏覽檢視返回按鈕Navigation view back button in the left navigation pane
左側瀏覽窗格中的返回按鈕The back button in the left navigation pane

上方瀏覽窗格中的瀏覽檢視返回按鈕Navigation view back button in the top navigation pane
上方瀏覽窗格中的返回按鈕The back button in the top navigation pane

程式碼範例Code example

重要

針對使用 Windows UI (WinUI) 程式庫工具組的任何專案,您會經歷相同的初步安裝步驟。For any project that makes use of the Windows UI (WinUI) Library toolkit, you go through the same preliminary setup setps. 如需更多背景、安裝和支援資訊,請參閱開始使用 Windows UI 程式庫For more background, setup, and support info, see Getting started with the Windows UI Library.

此範例會示範如何對於大型視窗大小的頂端瀏覽窗格和小型視窗大小的左側瀏覽窗格使用 NavigationViewThis example shows how you can use NavigationView with both a top navigation pane on large window sizes and a left navigation pane on small window sizes. 這可移除 VisualStateManager 中的 top 瀏覽設定,而調適為僅左側瀏覽。It can be adapted to left-only navigation by removing the top navigation settings in the VisualStateManager.

此範例示範對於許多常見情況設定適用瀏覽資料可用的建議方式。The example demonstrates a recommended way to set up navigation data that will work for many common scenarios. 這也會示範如何使用 NavigationView 的返回按鈕和鍵盤瀏覽來實作向後瀏覽。It also demonstrates how to implement backwards navigation with NavigationView's back button and keyboard navigation.

此程式碼假設您的應用程式包含將瀏覽的頁面,這些頁面的名稱如下:HomePageAppsPageGamesPageMusicPageMyContentPageSettingsPageThis code assumes that your app contains pages with the following names to navigate to: HomePage, AppsPage, GamesPage, MusicPage, MyContentPage, and SettingsPage. 這些頁面的程式碼不會顯示。Code for these pages is not shown.

重要

應用程式頁面的資訊會儲存在 ValueTuple 中。Information about the app's pages is stored in a ValueTuple. 此結構會要求應用程式專案的最小版本必須是 SDK 17763 或以上。This struct requires that the minimum version for your app project must be SDK 17763 or greater. 如果您使用 NavigationView 的 WinUI 版本鎖定舊版 Windows 10 為目標,您可以改為使用 System.ValueTuple NuGet 套件If you use the WinUI version of NavigationView to target earlier versions of Windows 10, you can use the System.ValueTuple NuGet package instead.

重要

此程式碼顯示如何使用 Windows UI 程式庫版本的 NavigationView。This code shows how to use the Windows UI Library version of NavigationView. 如果您改為使用平台版本的 NavigationView,應用程式專案的最小版本必須是 SDK 17763 或以上。If you use the platform version of NavigationView instead, the minimum version for your app project must be SDK 17763 or greater. 若要使用平台版本,請移除 muxc: 的所有參考。To use the platform version, remove all references to muxc:.

<Page ... xmlns:muxc="using:Microsoft.UI.Xaml.Controls" ... >
<Grid>
    <muxc:NavigationView x:Name="NavView"
                         Loaded="NavView_Loaded"
                         ItemInvoked="NavView_ItemInvoked"
                         BackRequested="NavView_BackRequested">
        <muxc:NavigationView.MenuItems>
            <muxc:NavigationViewItem Tag="home" Icon="Home" Content="Home"/>
            <muxc:NavigationViewItemSeparator/>
            <muxc:NavigationViewItemHeader x:Name="MainPagesHeader"
                                           Content="Main pages"/>
            <muxc:NavigationViewItem Tag="apps" Content="Apps">
                <muxc:NavigationViewItem.Icon>
                    <FontIcon FontFamily="Segoe MDL2 Assets" Glyph="&#xEB3C;"/>
                </muxc:NavigationViewItem.Icon>
            </muxc:NavigationViewItem>
            <muxc:NavigationViewItem Tag="games" Content="Games">
                <muxc:NavigationViewItem.Icon>
                    <FontIcon FontFamily="Segoe MDL2 Assets" Glyph="&#xE7FC;"/>
                </muxc:NavigationViewItem.Icon>
            </muxc:NavigationViewItem>
            <muxc:NavigationViewItem Tag="music" Icon="Audio" Content="Music"/>
        </muxc:NavigationView.MenuItems>

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

        <ScrollViewer>
            <Frame x:Name="ContentFrame" Padding="12,0,12,24" IsTabStop="True"
                   NavigationFailed="ContentFrame_NavigationFailed"/>
        </ScrollViewer>
    </muxc: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>

重要

此程式碼顯示如何使用 Windows UI 程式庫版本的 NavigationView。This code shows how to use the Windows UI Library version of NavigationView. 如果您改為使用平台版本的 NavigationView,應用程式專案的最小版本必須是 SDK 17763 或以上。If you use the platform version of NavigationView instead, the minimum version for your app project must be SDK 17763 or greater. 若要使用平台版本,請移除 muxc 的所有參考。To use the platform version, remove all references to muxc.

// Add "using" for WinUI controls.
// using muxc = Microsoft.UI.Xaml.Controls;

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

// List of ValueTuple holding the Navigation Tag and the relative Navigation Page
private readonly List<(string Tag, Type Page)> _pages = new List<(string Tag, Type Page)>
{
    ("home", typeof(HomePage)),
    ("apps", typeof(AppsPage)),
    ("games", typeof(GamesPage)),
    ("music", typeof(MusicPage)),
};

private void NavView_Loaded(object sender, RoutedEventArgs e)
{
    // You can also add items in code.
    NavView.MenuItems.Add(new muxc.NavigationViewItemSeparator());
    NavView.MenuItems.Add(new muxc.NavigationViewItem
    {
        Content = "My content",
        Icon = new SymbolIcon((Symbol)0xF1AD),
        Tag = "content"
    });
    _pages.Add(("content", typeof(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("home", new Windows.UI.Xaml.Media.Animation.EntranceNavigationTransitionInfo());

    // Add keyboard accelerators for backwards navigation.
    var goBack = new KeyboardAccelerator { Key = Windows.System.VirtualKey.GoBack };
    goBack.Invoked += BackInvoked;
    this.KeyboardAccelerators.Add(goBack);

    // ALT routes here
    var altLeft = new KeyboardAccelerator
    {
        Key = Windows.System.VirtualKey.Left,
        Modifiers = Windows.System.VirtualKeyModifiers.Menu
    };
    altLeft.Invoked += BackInvoked;
    this.KeyboardAccelerators.Add(altLeft);
}

private void NavView_ItemInvoked(muxc.NavigationView sender,
                                 muxc.NavigationViewItemInvokedEventArgs args)
{
    if (args.IsSettingsInvoked == true)
    {
        NavView_Navigate("settings", args.RecommendedNavigationTransitionInfo);
    }
    else if (args.InvokedItemContainer != null)
    {
        var navItemTag = args.InvokedItemContainer.Tag.ToString();
        NavView_Navigate(navItemTag, 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(muxc.NavigationView sender,
                                      muxc.NavigationViewSelectionChangedEventArgs args)
{
    if (args.IsSettingsSelected == true)
    {
        NavView_Navigate("settings", args.RecommendedNavigationTransitionInfo);
    }
    else if (args.SelectedItemContainer != null)
    {
        var navItemTag = args.SelectedItemContainer.Tag.ToString();
        NavView_Navigate(navItemTag, args.RecommendedNavigationTransitionInfo);
    }
}

private void NavView_Navigate(
    string navItemTag,
    Windows.UI.Xaml.Media.Animation.NavigationTransitionInfo transitionInfo)
{
    Type _page = null;
    if (navItemTag == "settings")
    {
        _page = typeof(SettingsPage);
    }
    else
    {
        var item = _pages.FirstOrDefault(p => p.Tag.Equals(navItemTag));
        _page = item.Page;
    }
    // Get the page type before navigation so you can prevent duplicate
    // entries in the backstack.
    var preNavPageType = ContentFrame.CurrentSourcePageType;

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

private void NavView_BackRequested(muxc.NavigationView sender,
                                   muxc.NavigationViewBackRequestedEventArgs args)
{
    On_BackRequested();
}

private void BackInvoked(KeyboardAccelerator sender,
                         KeyboardAcceleratorInvokedEventArgs args)
{
    On_BackRequested();
    args.Handled = true;
}

private bool On_BackRequested()
{
    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;
}

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 = (muxc.NavigationViewItem)NavView.SettingsItem;
        NavView.Header = "Settings";
    }
    else if (ContentFrame.SourcePageType != null)
    {
        var item = _pages.FirstOrDefault(p => p.Page == e.SourcePageType);

        NavView.SelectedItem = NavView.MenuItems
            .OfType<muxc.NavigationViewItem>()
            .First(n => n.Tag.Equals(item.Tag));

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

注意

如需此程式碼範例的 C++/WinRT 版本,請先根據空白應用程式 (C++/WinRT) 專案範本建立新的專案,然後將清單中的程式碼加入至指定的原始程式碼檔案。For the C++/WinRT version of this code example, begin by creating a new project based on the Blank App (C++/WinRT) project template, and then add the code in the listing to the indicated source code files. 若要使用完全如清單中所示的原始程式碼,請將您的新專案命名為 NavigationViewCppWinRTTo use the source code exactly as shown in the listing, name your new project NavigationViewCppWinRT

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

// pch.h
...
#include "winrt/Windows.UI.Xaml.Input.h"
#include "winrt/Windows.UI.Xaml.Media.Animation.h"
#include "winrt/Microsoft.UI.Xaml.Controls.h"
#include "winrt/Microsoft.UI.Xaml.XamlTypeInfo.h"

// MainPage.h
#pragma once

#include "MainPage.g.h"

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

namespace wuxc
{
    using namespace winrt::Windows::UI::Xaml::Controls;
};

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

        double NavViewCompactModeThresholdWidth();
        void ContentFrame_NavigationFailed(
            Windows::Foundation::IInspectable const& /* sender */,
            Windows::UI::Xaml::Navigation::NavigationFailedEventArgs const& args);
        void NavView_Loaded(
            Windows::Foundation::IInspectable const& /* sender */,
            Windows::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(
            std::wstring navItemTag,
            Windows::UI::Xaml::Media::Animation::NavigationTransitionInfo const& transitionInfo);
        void NavView_BackRequested(
            muxc::NavigationView const& /* sender */,
            muxc::NavigationViewBackRequestedEventArgs const& /* args */);
        void BackInvoked(
            Windows::UI::Xaml::Input::KeyboardAccelerator const& /* sender */,
            Windows::UI::Xaml::Input::KeyboardAcceleratorInvokedEventArgs const& args);
        bool On_BackRequested();
        void On_Navigated(
            Windows::Foundation::IInspectable const& /* sender */,
            Windows::UI::Xaml::Navigation::NavigationEventArgs const& args);

    private:
        // Vector of std::pair holding the Navigation Tag and the relative Navigation Page.
        std::vector<std::pair<std::wstring, Windows::UI::Xaml::Interop::TypeName>> m_pages;
    };
}

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

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

namespace winrt::NavigationViewCppWinRT::implementation
{
    MainPage::MainPage()
    {
        InitializeComponent();
        m_pages.push_back(std::make_pair<std::wstring, Windows::UI::Xaml::Interop::TypeName>
            (L"home", winrt::xaml_typename<NavigationViewCppWinRT::HomePage>()));
        m_pages.push_back(std::make_pair<std::wstring, Windows::UI::Xaml::Interop::TypeName>
            (L"apps", winrt::xaml_typename<NavigationViewCppWinRT::AppsPage>()));
        m_pages.push_back(std::make_pair<std::wstring, Windows::UI::Xaml::Interop::TypeName>
            (L"games", winrt::xaml_typename<NavigationViewCppWinRT::GamesPage>()));
        m_pages.push_back(std::make_pair<std::wstring, Windows::UI::Xaml::Interop::TypeName>
            (L"music", winrt::xaml_typename<NavigationViewCppWinRT::MusicPage>()));
    }

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

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

    // List of ValueTuple holding the Navigation Tag and the relative Navigation Page
    std::vector<std::pair<std::wstring, Windows::UI::Xaml::Interop::TypeName>> m_pages;

    void MainPage::NavView_Loaded(
        Windows::Foundation::IInspectable const& /* sender */,
        Windows::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(wuxc::SymbolIcon(static_cast<wuxc::Symbol>(0xF1AD)));
        navigationViewItem.Tag(winrt::box_value(L"content"));
        NavView().MenuItems().Append(navigationViewItem);
        m_pages.push_back(
            std::make_pair<std::wstring, Windows::UI::Xaml::Interop::TypeName>(
                L"content", winrt::xaml_typename<NavigationViewCppWinRT::MyContentPage>()));

        // 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(L"home",
            Windows::UI::Xaml::Media::Animation::EntranceNavigationTransitionInfo());

        // Add keyboard accelerators for backwards navigation.
        Windows::UI::Xaml::Input::KeyboardAccelerator goBack;
        goBack.Key(Windows::System::VirtualKey::GoBack);
        goBack.Invoked({ this, &MainPage::BackInvoked });
        KeyboardAccelerators().Append(goBack);

        // ALT routes here
        Windows::UI::Xaml::Input::KeyboardAccelerator altLeft;
        goBack.Key(Windows::System::VirtualKey::Left);
        goBack.Modifiers(Windows::System::VirtualKeyModifiers::Menu);
        goBack.Invoked({ this, &MainPage::BackInvoked });
        KeyboardAccelerators().Append(altLeft);
    }

    void MainPage::NavView_ItemInvoked(
        Windows::Foundation::IInspectable const& /* sender */,
        muxc::NavigationViewItemInvokedEventArgs const& args)
    {
        if (args.IsSettingsInvoked())
        {
            NavView_Navigate(L"settings", args.RecommendedNavigationTransitionInfo());
        }
        else if (args.InvokedItemContainer())
        {
            NavView_Navigate(
                winrt::unbox_value_or<winrt::hstring>(
                    args.InvokedItemContainer().Tag(), L"").c_str(),
                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(L"settings", args.RecommendedNavigationTransitionInfo());
        }
        else if (args.SelectedItemContainer())
        {
            NavView_Navigate(
                winrt::unbox_value_or<winrt::hstring>(
                    args.SelectedItemContainer().Tag(), L"").c_str(),
                args.RecommendedNavigationTransitionInfo());
        }
    }

    void MainPage::NavView_Navigate(
        std::wstring navItemTag,
        Windows::UI::Xaml::Media::Animation::NavigationTransitionInfo const& transitionInfo)
    {
        Windows::UI::Xaml::Interop::TypeName pageTypeName;
        if (navItemTag == L"settings")
        {
            pageTypeName = winrt::xaml_typename<NavigationViewCppWinRT::SettingsPage>();
        }
        else
        {
            for (auto&& eachPage : m_pages)
            {
                if (eachPage.first == navItemTag)
                {
                    pageTypeName = eachPage.second;
                    break;
                }
            }
        }
        // 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 (pageTypeName.Name != L"" && preNavPageType.Name != pageTypeName.Name)
        {
            ContentFrame().Navigate(pageTypeName, nullptr, transitionInfo);
        }
    }

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

    void MainPage::BackInvoked(
        Windows::UI::Xaml::Input::KeyboardAccelerator const& /* sender */,
        Windows::UI::Xaml::Input::KeyboardAcceleratorInvokedEventArgs const& args)
    {
        On_BackRequested();
        args.Handled(true);
    }

    bool MainPage::On_BackRequested()
    {
        if (!ContentFrame().CanGoBack())
            return false;

        // Don't go back if the nav pane is overlaid.
        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 */,
        Windows::UI::Xaml::Navigation::NavigationEventArgs const& args)
    {
        NavView().IsBackEnabled(ContentFrame().CanGoBack());

        if (ContentFrame().SourcePageType().Name ==
            winrt::xaml_typename<NavigationViewCppWinRT::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&& eachPage : m_pages)
            {
                if (eachPage.second.Name == args.SourcePageType().Name)
                {
                    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 == eachPage.first)
                                {
                                    NavView().SelectedItem(navigationViewItem);
                                    NavView().Header(navigationViewItem.Content());
                                }
                            }
                        }
                    }
                    break;
                }
            }
        }
    }
}

替代的 C++/WinRT 實作Alternative C++/WinRT implementation

上述的 C# 和 C++ /WinRT 程式碼經過精心設計,以便您可以對這兩個版本使用相同的 XAML 標記。The C# and C++/WinRT code show above is designed so that you can use the same XAML markup for both versions. 不過,還有另一種方式可以實作本節中所述的 C++/WinRT 版本,建議您採用這個方式。However, there is another way of implementing the C++/WinRT version described in this section, which you may prefer.

以下是替代版本的 NavView_ItemInvoked 處理常式。Below is an alternative version of the NavView_ItemInvoked handler. 此版本處理常式的技巧需要先儲存 (在 NavigationViewItem 的標籤中) 要瀏覽的頁面所用的完整類型名稱。The technique in this version of the handler involves you first storing (in the tag of the NavigationViewItem) the full type name of the page to which you want to navigate. 在處理常式中,您會對該值進行 unbox 處理,將它變成 Windows::UI::Xaml::Interop::TypeName 物件,並使用它來瀏覽至目的地頁面。In the handler, you unbox that value, turn it into a Windows::UI::Xaml::Interop::TypeName object, and use that to navigate to the destination page. 不需要上述範例中名稱為 _pages 的對應變數,而且您將能夠建立單元測試,確認標記內的值屬於有效類型。There's no need for the mapping variable named _pages that you see in examples above; and you'll be able to create unit tests confirming that the values inside your tags are of a valid type. 另請參閱使用 C++/WinRT,Boxing 和 unboxing 純量數值到 IInspectableAlso see Boxing and unboxing scalar values to IInspectable with C++/WinRT.

void MainPage::NavView_ItemInvoked(
    Windows::Foundation::IInspectable const & /* sender */,
    Windows::UI::Xaml::Controls::NavigationViewItemInvokedEventArgs const & args)
{
    if (args.IsSettingsInvoked())
    {
        // Navigate to Settings.
    }
    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;
        ContentFrame().Navigate(pageTypeName, nullptr);
    }
}

階層式瀏覽Hierarchical navigation

有些應用程式可能有更複雜的階層式結構,而不只需要瀏覽項目的簡單列表。Some apps may have a more complex hierarchical structure that requires more than just a flat list of navigation items. 您可能想使用最上層的瀏覽項目來顯示頁面的類別,以及可顯示特定頁面的子系項目。You may want to use top-level navigation items to display categories of pages, with children items displaying specific pages. 如果您的中樞樣式頁面只會連結至其他頁面,這也很有用。It is also useful if you have hub-style pages that only link to other pages. 針對這類案例,您應該建立階層式 NavigationView。For these kinds of cases, you should create a hierarchical NavigationView.

若要在窗格中顯示巢狀瀏覽項目的階層式清單,請使用 NavigationViewItemMenuItems 屬性或 MenuItemsSource 屬性。To show a hierarchical list of nested navigation items in the pane, use either the MenuItems property or the MenuItemsSource property of NavigationViewItem. 每個 NavigationViewItem 均可包含其他 NavigationViewItem 和組織項目 (例如項目標頭和分隔符號)。Each NavigationViewItem can contain other NavigationViewItems and organizing elements like item headers and separators. 若要在使用 MenuItemsSource 時顯示階層式清單,請將 ItemTemplate 設定為 NavigationViewItem,並將其 MenuItemsSource 屬性繫結至階層的下一個層級。To show a hierarchical list when using MenuItemsSource, set the ItemTemplate to be a NavigationViewItem, and bind its MenuItemsSource property to the next level of the hierarchy.

雖然 NavigationViewItem 可以包含任意數目的巢狀層級,但建議讓應用程式的瀏覽階層保持淺層。Although NavigationViewItem can contain any number of nested levels, we recommend keeping your app’s navigation hierarchy shallow. 我們認為兩個層級兼具可用性且容易理解。We believe two levels is ideal for usability and comprehension.

NavigationView 會以頂端、左側和 LeftCompact 窗格顯示模式顯示階層。NavigationView shows hierarchy in Top, Left, and LeftCompact pane display modes. 以下是展開的樹狀子目錄在每個窗格顯示模式中的外觀:Here is what an expanded subtree looks like in each of the pane display modes:

具有階層的 NavigationView

在標記中新增項目的階層Adding a hierarchy of items in markup

在標記中宣告應用程式瀏覽階層。Declare app navigation hierarchy in markup.

<!-- xmlns:muxc="using:Microsoft.UI.Xaml.Controls" -->
<muxc:NavigationView>
    <muxc:NavigationView.MenuItems>
        <muxc:NavigationViewItem Content="Home" Icon="Home" ToolTipService.ToolTip="Home"/>
        <muxc:NavigationViewItem Content="Collections" Icon="Keyboard" ToolTipService.ToolTip="Collections">
            <muxc:NavigationViewItem.MenuItems>
                <muxc:NavigationViewItem Content="Notes" Icon="Page" ToolTipService.ToolTip="Notes"/>
                <muxc:NavigationViewItem Content="Mail" Icon="Mail" ToolTipService.ToolTip="Mail"/>
            </muxc:NavigationViewItem.MenuItems>
        </muxc:NavigationViewItem>
    </muxc:NavigationView.MenuItems>
</muxc:NavigationView>

使用資料繫結新增項目的階層Adding a hierarchy of items using data binding

將功能表項目的階層新增至 NavigationViewAdd a hierarchy of menu items to the NavigationView by

  • 將 MenuItemsSource 屬性繫結至階層式資料binding the MenuItemsSource property to the hierarchical data
  • 將項目範本定義為 NavigationViewMenuItem,將其內容設為功能表項目的標籤,並將其 MenuItemsSource 屬性繫結至階層的下一個層級defining the item template to be a NavigationViewMenuItem, with its Content set to be the label of the menu item, and its MenuItemsSource property bound to the next level of the hierarchy

這個範例也會示範展開摺疊事件。This example also demonstrates the Expanding and Collapsed events. 具有子系的功能表項目會引發這些事件。These events are raised for a menu item with children.

<Page ... xmlns:muxc="using:Microsoft.UI.Xaml.Controls" ... >
    <Page.Resources>
        <DataTemplate x:Key="NavigationViewMenuItem" x:DataType="local:Category">
            <muxc:NavigationViewItem Content="{x:Bind Name}" MenuItemsSource="{x:Bind Children}"/>
        </DataTemplate>
    </Page.Resources>

    <Grid>
        <muxc: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>
        </muxc: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);
    }
}

選項Selection

根據預設,任何項目都可以包含子系、加以叫用或選取。By default, any item can contain children, be invoked, or be selected.

為使用者提供瀏覽選項的階層式樹狀結構時,您可選擇讓父系項目變為不可選取,例如當您的應用程式沒有與該父系項目相關聯的目的地頁面時。When providing users with a hierarchical tree of navigation options, you may choose to make parent items non-selectable, for example when your app doesn't have a destination page associated with that parent item. 如果父系項目可選取,建議您使用左側展開或頂端窗格顯示模式。If your parent items are selectable, it's recommend you use the Left-Expanded or Top pane display modes. LeftCompact 模式會讓使用者瀏覽至父系項目,以便在每次叫用時開啟子系樹狀子目錄。LeftCompact mode will cause the user to navigate to the parent item in order to open the child subtree every time it's invoked.

選取的項目會沿著其左邊緣 (在左側模式中) 或沿著其底部邊緣 (在頂端模式中) 繪製其選取指標。Selected items will draw their selection indicators along their left edge when in left mode or their bottom edge when in top mode. 以下顯示已選取父系項目的情況下,左側和頂端模式中的 NavigationView。Shown below are NavigationViews in left and top mode where a parent item is selected.

已選取父系的左側模式 NavigationView

已選取父系的頂端模式 NavigationView

選取的項目不一定會保持可見狀態。The selected item may not always remain visible. 如果已選取摺疊/非展開樹狀子目錄中的子系,其第一個可見上階會顯示為已選取。If a child in a collapsed/non-expanded subtree is selected, their first visible ancestor will show as selected. 如果樹狀子目錄已展開,選取指標會移回選取的項目。The selection indicator will move back to the selected item if/when the sub-tree is expanded.

例如,在上圖中,使用者可以選取「行事曆」項目,接著可以摺疊其樹狀子目錄。For example - in the above image, the Calendar item may be selected by the user, and then the user may collapse its subtree. 在此情況下,選取指標會顯示在「帳戶」項目底下,因為「帳戶」是「行事曆」的第一個可見上階。In this case, the selection indicator would show up underneath the Account item as Account is Calendar's first visible ancestor. 當使用者再次展開樹狀子目錄時,選取指標將移回「行事曆」項目。The selection indicator will move back to the Calendar item as the user expands the subtree again.

整個 NavigationView 將不會顯示一個以上的選取指標。The entire NavigationView will show no more than one selection indicator.

在頂端和左側模式中,按一下 NavigationViewItem 上的箭號將會展開或摺疊樹狀子目錄。In both Top and Left modes, clicking the arrows on NavigationViewItems will expand or collapse the subtree. 按一下或點擊 NavigationViewItem 上的「其他地方」將會觸發 ItemInvoked 事件,同時也會摺疊或展開樹狀子目錄。Clicking or tapping elsewhere on the NavigationViewItem will trigger the ItemInvoked event, and it will also collapse or expand the subtree.

若要防止項目在叫用時顯示選取指標,請將其 SelectsOnInvoked 屬性設定為 False,如下所示:To prevent an item from showing the selection indicator when invoked, set its SelectsOnInvoked property to False, as shown below:

<Page ... xmlns:muxc="using:Microsoft.UI.Xaml.Controls" ... >
    <Page.Resources>
        <DataTemplate x:Key="NavigationViewMenuItem" x:DataType="local:Category">
            <muxc:NavigationViewItem Content="{x:Bind Name}"
            MenuItemsSource="{x:Bind Children}"
            SelectsOnInvoked="{x:Bind IsLeaf}"/>
        </DataTemplate>
    </Page.Resources>

    <Grid>
        <muxc:NavigationView x:Name="navview" 
    MenuItemsSource="{x:Bind Categories, Mode=OneWay}" 
    MenuItemTemplate="{StaticResource NavigationViewMenuItem}">
        </muxc: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);
}
...

階層式 NavigationView 內的鍵盤輸入Keyboarding within hierarchical NavigationView

使用者可以使用其鍵盤,將焦點移到瀏覽檢視的周圍。Users can move focus around the navigation view using their keyboard. 方向鍵會在窗格內公開「內部瀏覽」,並遵循 樹狀檢視中提供的互動。The arrow keys expose "inner navigation" within the pane and follow the interactions provided in tree view. 按鍵動作會在瀏覽 NavigationView 或其飛出視窗功能表 (其顯示在 HierarchicalNavigationView 的頂端和左側精簡模式中) 時變更。The key actions change when navigating through the NavigationView or its flyout menu, which is displayed in Top and Left-compact modes of HierarchicalNavigationView. 以下是每個按鍵可在階層式 NavigationView 中採取的特定動作:Below are the specific actions that each key can take in a hierarchical NavigationView:

按鍵Key 在左側模式中In Left Mode 在頂端模式中In Top Mode 在飛出視窗中In Flyout
UpUp 將焦點移至目前聚焦項目正上方的項目。Moves focus to the item directly above the item currently in focus. 不執行任何動作。Does nothing. 將焦點移至目前聚焦項目正上方的項目。Moves focus to the item directly above the item currently in focus.
DownDown 將焦點移到目前聚焦項目的正下方。*Moves focus directly below the item currently in focus.* 不執行任何動作。Does nothing. 將焦點移到目前聚焦項目的正下方。*Moves focus directly below the item currently in focus.*
RightRight 不執行任何動作。Does nothing. 將焦點直接移至目前聚焦項目右邊的項目。Moves focus to the item directly to the right of the item currently in focus. 不執行任何動作。Does nothing.
LeftLeft 不執行任何動作。Does nothing. 將焦點直接移至目前聚焦項目左邊的項目。Moves focus to the item directly to the left the item currently in focus. 不執行任何動作。Does nothing.
空格鍵/Enter 鍵Space/Enter 如果項目具有子系,則展開/摺疊項目,而不要變更焦點。If item has children, expands/collapses item and does not change focus. 如果項目具有子系,則將子系展開到飛出視窗中,並將焦點置於飛出視窗中的項目。If item has children, expands children into a flyout and places focus on first item in flyout. 叫用/選取項目並關閉飛出視窗。Invokes/selects item and closes flyout.
EscEsc 不執行任何動作。Does nothing. 不執行任何動作。Does nothing. 關閉飛出視窗。Closes flyout.

空格鍵或 Enter 鍵一律會叫用/選取一個項目。The space or enter key always invokes/selects an item.

*請注意,項目不需要在視覺上相鄰,焦點會從窗格清單中的最後一個項目移至 [設定] 項目。*Note that the items do not need to be visually adjacent, focus will move from the last item in the pane's list to the settings item.

窗格背景Pane Backgrounds

根據顯示模式,NavigationView 窗格預設使用不同的背景:By default, the NavigationView pane uses a different background depending on the display mode:

  • 窗格在左側展開而與內容並排時 (在左側模式中),會顯示純灰色。the pane is a solid grey color when expanded on the left, side-by-side with the content (in Left mode).
  • 窗格會在開始時使用應用程式內壓克力做為內容頂端的重疊 (在頂端、基本或精簡模式中)。the pane uses in-app acrylic when open as an overlay on top of content (in Top, Minimal, or Compact mode).

若要修改窗格背景,您可以覆寫轉譯每個模式的背景所用的 XAML 佈景主題資源。To modify the pane background, you can override the XAML theme resources used to render the background in each mode. (會使用這項技巧,而非使用單獨的 PaneBackground 屬性,以支援不同的顯示模式下的不同背景。)(This technique is used rather than a single PaneBackground property in order to support different backgrounds for different display modes.)

下表顯示會在每個顯示模式中使用哪個佈景主題資源。This table shows which theme resource is used in each display mode.

顯示模式Display mode 佈景主題資源Theme resource
LeftLeft NavigationViewExpandedPaneBackgroundNavigationViewExpandedPaneBackground
LeftCompactLeftCompact
LeftMinimalLeftMinimal
NavigationViewDefaultPaneBackgroundNavigationViewDefaultPaneBackground
頁首Top NavigationViewTopPaneBackgroundNavigationViewTopPaneBackground

此範例示範如何覆寫 App.xaml 中的佈景主題資源。This example shows how to override the theme resources in App.xaml. 您覆寫佈景主題資源時,應該至少一律提供「預設」和「高對比」資源字典,並且視需要提供「亮色調」或「暗色調」資源的字典。When you override theme resources, you should always provide "Default" and "HighContrast" resource dictionaries at a minimum, and dictionaries for "Light" or "Dark" resources as needed. 如需詳細資訊,請參閱 ResourceDictionary.ThemeDictionariesFor more info, see ResourceDictionary.ThemeDictionaries.

重要

此程式碼顯示如何使用 Windows UI 程式庫版本的 AcrylicBrush。This code shows how to use the Windows UI Library version of AcrylicBrush. 如果您改為使用平台版本的 AcrylicBrush,應用程式專案的最小版本必須是 SDK 16299 或以上。If you use the platform version of AcrylicBrush instead, the minimum version for your app project must be SDK 16299 or greater. 若要使用平台版本,請移除 muxm: 的所有參考。To use the platform version, remove all references to 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>

前幾個空白字元Top whitespace

IsTitleBarAutoPaddingEnabled 屬性需要 Windows UI 程式庫 2.2 或更新版本。The IsTitleBarAutoPaddingEnabled property requires the Windows UI Library 2.2 or later.

有些應用程式選擇自訂其視窗標題列,可能會將其應用程式內容延伸到標題列區域。Some apps choose to customize their window's title bar, potentially extending their app content into the title bar area. 當 NavigationView 是使用 ExtendViewIntoTitleBar API,在應用程式中延伸至標題列的根元素時,控制項會自動調整其互動式元素的位置,以避免與可拖曳的區域重疊。When NavigationView is the root element in apps that extend into the title bar using the ExtendViewIntoTitleBar API, the control automatically adjusts the position of its interactive elements to prevent overlap with the draggable region.

延伸至標題列的應用程式

如果您的應用程式透過呼叫 Window.SetTitleBar 方法指定可拖曳的區域,而您想要讓 [上一頁] 和 [功能表] 按鈕更接近應用程式視窗的頂端,請將 IsTitleBarAutoPaddingEnabled 設定為 falseIf your app specifies the draggable region by calling the Window.SetTitleBar method and you would prefer to have the back and menu buttons draw closer to the top of your app window, set IsTitleBarAutoPaddingEnabled to false.

應用程式延伸至標題列而不需額外填補

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

備註Remarks

若要進一步調整 NavigationView 標題區域的位置,請覆寫 NavigationViewHeaderMargin XAML 主題資源,例如在頁面資源中。To further adjust the position of NavigationView's header area, override the NavigationViewHeaderMargin XAML theme resource, for example in your Page resources.

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

此主題資源會修改 NavigationView.Header 周圍的邊界。This theme resource modifies the margin around NavigationView.Header.