Nuta
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować się zalogować lub zmienić katalog.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Kontrolka NavigationView zapewnia nawigację najwyższego poziomu dla aplikacji. Dostosowuje się do różnych rozmiarów ekranu i obsługuje zarówno górny, jak i lewy styl nawigacji.
Element NavigationView obsługuje zarówno górny, jak i lewy panel nawigacji lub menu
Czy jest to właściwa kontrola?
NavigationView to adaptacyjna kontrolka nawigacji, która dobrze sprawdza się w następujących celach:
- Zapewnienie spójnego środowiska nawigacji w całej aplikacji.
- Oszczędzanie miejsca na ekranie na mniejszych oknach.
- Organizowanie dostępu do wielu kategorii nawigacji.
Aby zapoznać się z innymi wzorcami nawigacji, zobacz Podstawy projektowania nawigacji.
Tworzenie widoku nawigacji
- Ważne interfejsy API:klasa NavigationView
Aplikacja Galeria WinUI 3 zawiera interaktywne przykłady większości kontrolek, funkcji i funkcji interfejsu WinUI 3. Pobierz aplikację ze Sklepu Microsoft lub pobierz kod źródłowy w witrynie GitHub
W tym przykładzie pokazano, jak utworzyć prosty widok nawigacji w języku XAML.
<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>
Tryby wyświetlania
Za pomocą właściwości PaneDisplayMode można skonfigurować różne style nawigacji lub tryby wyświetlania dla elementu NavigationView.
Do góry
Okienko znajduje się nad zawartością.PaneDisplayMode="Top"
Zalecamy korzystanie z górnej nawigacji , gdy:
- Masz 5 lub mniej kategorii nawigacji najwyższego poziomu, które są równie ważne, a wszelkie dodatkowe kategorie, które znajdują się w menu rozwijanym nadmiarowym, są uznawane za mniej ważne.
- Musisz wyświetlić wszystkie opcje nawigacji na ekranie.
- Potrzebujesz więcej miejsca na zawartość aplikacji.
- Ikony nie mogą wyraźnie opisywać kategorii nawigacji aplikacji.
Lewo
Panel jest rozwinięty i umieszczony po lewej stronie zawartości.PaneDisplayMode="Left"
Zalecamy nawigację po lewej stronie, gdy:
- Masz 5–10 równie ważnych kategorii nawigacji najwyższego poziomu.
- Chcesz, aby kategorie nawigacji były bardzo widoczne, z mniej miejsca na inną zawartość aplikacji.
LewoKompaktowy
W okienku są wyświetlane tylko ikony do momentu otwarcia i umieszczone po lewej stronie zawartości. Po otwarciu okienko nakłada się na zawartość.PaneDisplayMode="LeftCompact"
LeftMinimal
Tylko przycisk menu jest wyświetlany do momentu otwarcia okienka. Po otwarciu okienko nakłada się na lewą stronę zawartości.PaneDisplayMode="LeftMinimal"
Auto
Domyślnie właściwość PaneDisplayMode jest ustawiona na Auto. W trybie Auto widok NavigationView dostosowuje się między LeftMinimal, gdy okno jest wąskie, aby LeftCompact, a następnie Left, gdy okno staje się szersze. Aby uzyskać więcej informacji, przejdź do sekcji dotyczącej adaptacyjnego zachowania.
domyślne adaptacyjne zachowanie nawigacji po lewej stronie 
Domyślne zachowanie adaptacyjne elementu NavigationView
Anatomia
Te obrazy przedstawiają układ okienka, nagłówka i obszaru zawartości kontrolki po skonfigurowaniu dla górnej lub nawigacji po lewej stronie.
układu
Układ nawigacji u góry
Układ nawigacji po lewej stronie
Panel
Możesz użyć właściwości PaneDisplayMode, aby umieścić okienko nad zawartością lub z lewej strony zawartości.
Okienko NavigationView może zawierać:
- Obiekty NavigationViewItem. Elementy nawigacji do przechodzenia do określonych stron.
- NavigationViewItemSeparator obiekty. Separatory do grupowania elementów nawigacji. Ustaw właściwość nieprzezroczystości na 0, aby wyświetlić separator jako spację.
- obiekty NavigationViewItemHeader. Nagłówki do etykietowania grup elementów.
- Opcjonalna kontrolka AutoSuggestBox umożliwiająca wyszukiwanie na poziomie aplikacji. Przypisz kontrolkę do właściwości NavigationView.AutoSuggestBox .
- Opcjonalny punkt wejścia dla ustawień aplikacji . Aby ukryć element ustawień, ustaw właściwość IsSettingsVisible na
false.
Okienko po lewej stronie zawiera również następujące elementy:
- Przycisk menu, aby przełączyć okienko otwarte i zamknięte. W większych oknach aplikacji po otwarciu okienka możesz ukryć ten przycisk przy użyciu właściwości IsPaneToggleButtonVisible .
Element NavigationView ma przycisk Wstecz umieszczony w lewym górnym rogu okienka. Nie obsługuje jednak automatycznej nawigacji wstecznej ani nie dodaje zawartości do stosu wstecznego. Aby włączyć nawigację wstecz, zobacz sekcję nawigacji wstecz .
Oto szczegółowa anatomia okienka dla pozycji górnego i lewego okienka.
Górne okienko nawigacji
- Nagłówki
- Elementy nawigacji
- Separatory
- AutoSuggestBox (opcjonalnie)
- Przycisk Ustawienia (opcjonalnie)
Lewe okienko nawigacji
- Przycisk menu
- Elementy nawigacji
- Separatory
- Nagłówki
- AutoSuggestBox (opcjonalnie)
- Przycisk Ustawienia (opcjonalnie)
Elementy menu stopki
Możesz użyć FooterMenuItems, aby umieścić elementy nawigacji na końcu okienka nawigacji, w przeciwieństwie do właściwości MenuItems, która umieszcza elementy na początku okienka.
FooterMenuItems zostanie wyświetlone przed elementem Settings domyślnie. Element Settings można nadal przełączać przy użyciu właściwości IsSettingsVisible.
W elementach menu stopki należy umieścić tylko elementy nawigacji — każda inna zawartość, która musi być wyrównana do stopki okna, powinna zostać umieszczona w sekcji PaneFooter.
Aby zapoznać się z przykładem dodawania elementów FooterMenuItems dla NavigationView, zobacz klasę FooterMenuItems.
Na poniższej ilustracji przedstawiono widok nawigacji NavigationView z elementami Account, Your Carti Pomoc w menu stopki.
Stopka panelu
Możesz umieścić dowolną zawartość w stopce okienka, dodając ją do właściwości PaneFooter.
stopka górnego panelu
Stopka panelu 
stopkę okienka po lewej stronie
Tytuł i nagłówek panelu
Można umieścić zawartość tekstową w nagłówku obszaru okienka, ustawiając właściwość PaneTitle. Pobiera ciąg i wyświetla tekst obok przycisku menu.
Aby dodać zawartość nietekstową, taką jak obraz lub logo, możesz umieścić dowolny element w nagłówku okienka, dodając go do właściwości PaneHeader .
Jeśli ustawiono zarówno pozycje PaneTitle, jak i PaneHeader, zawartość jest ułożona poziomo obok przycisku menu, przy czym tytuł PaneTitle znajduje się najbliżej przycisku menu.
górnej części nagłówka okienka
nagłówka górnego okienka
Nagłówek okienka po lewej stronie
Zawartość okienka
Zawartość wolnego formularza można umieścić w okienku, dodając ją do właściwości PaneCustomContent .
Zawartość niestandardowa górnego okienka
Zawartość niestandardowa w lewym panelu
Header
Tytuł strony można dodać, ustawiając właściwość nagłówka .
nagłówka
Obszar nagłówka jest wyrównany pionowo z przyciskiem nawigacyjnym wewnątrz lewej części okienka, a znajduje się poniżej okienka, gdy jest ono w górnej pozycji. Ma stałą wysokość 52 pikseli. Jej celem jest przechowywanie tytułu strony dla wybranej kategorii nawigacji. Nagłówek jest umieszczony u góry strony i służy jako punkt zaczepienia przy przewijaniu obszaru zawartości.
Nagłówek jest widoczny za każdym razem, gdy NavigationView jest w trybie wyświetlania Minimal. Możesz ukryć nagłówek w innych trybach, które są używane na większych szerokościach okien. Aby ukryć nagłówek, ustaw właściwość AlwaysShowHeader na false.
Content
zawartość NavigationView
Obszar zawartości to miejsce, w którym jest wyświetlana większość informacji dla wybranej kategorii nawigacji.
Zalecamy użycie 12 pikseli marginesu dla obszaru zawartości, gdy NavigationView jest w trybie Minimal i 24 pikseli marginesu, gdy nie.
Zachowanie adaptacyjne
Domyślnie widok NavigationView automatycznie zmienia tryb wyświetlania na podstawie ilości dostępnego miejsca na ekranie. Właściwości CompactModeThresholdWidth i ExpandedModeThresholdWidth określają punkty przerwania, w których zmienia się tryb wyświetlania. Możesz zmodyfikować te wartości, aby dostosować zachowanie trybu adaptacyjnego wyświetlania.
Default
Gdy parametr PaneDisplayMode jest ustawiony na wartość domyślną Auto, adaptacyjne zachowanie polega na:
- Rozszerzony panel po lewej stronie przy dużych szerokościach okien (1008 pikseli lub więcej).
- Lewe okienko nawigacyjne tylko z ikonami (
LeftCompact) w średnim zakresie szerokości okna od 641px do 1007px. - Tylko przycisk menu (
LeftMinimal) o małych szerokościach okien (640 pikseli lub mniej).
Aby uzyskać więcej informacji na temat rozmiarów okien na potrzeby zachowania adaptacyjnego, zobacz Rozmiary ekranu i punkty przerwania.
domyślne adaptacyjne zachowanie nawigacji po lewej stronie 
Domyślne zachowanie adaptacyjne elementu NavigationView
Minimalny
Drugi typowy wzorzec adaptacyjny polega na użyciu rozwiniętego okienka po lewej stronie w dużych szerokościach okien i tylko przycisku menu zarówno na średnich, jak i małych szerokościach okien.
Zalecamy następujące działania w przypadku:
- Potrzebujesz więcej miejsca na zawartość aplikacji o mniejszej szerokości okna.
- Kategorie nawigacji nie mogą być wyraźnie reprezentowane za pomocą ikon.
NavigationView "minimalne" adaptacyjne zachowanie
Aby skonfigurować to zachowanie, ustaw wartość CompactModeThresholdWidth na szerokość, w której ma zostać zwinięte okienko. W tym miejscu zostanie zmieniona z wartości domyślnej 640 na 1007. Należy również ustawić wartość ExpandedModeThresholdWidth, aby upewnić się, że wartości nie powodują konfliktu.
<NavigationView CompactModeThresholdWidth="1007" ExpandedModeThresholdWidth="1007"/>
Kompaktowy
Trzeci typowy wzorzec adaptacyjny polega na użyciu rozszerzonego okienka po lewej stronie przy dużych szerokościach okien oraz kompaktowego, tylko z ikonami, okienka nawigacji po lewej stronie zarówno przy średnich, jak i małych szerokościach okien.
Zalecamy następujące działania w przypadku:
- Ważne jest, aby zawsze pokazywać wszystkie opcje nawigacji na ekranie.
- Kategorie nawigacji można wyraźnie przedstawiać za pomocą ikon.
NavigationView „kompaktowe” zachowanie adaptacyjne
Aby skonfigurować to zachowanie, ustaw wartość CompactModeThresholdWidth na 0.
<NavigationView CompactModeThresholdWidth="0"/>
Brak zachowania adaptacyjnego
Aby wyłączyć automatyczne zachowanie adaptacyjne, ustaw parametr PaneDisplayMode na wartość inną niż Auto. W tym miejscu jest ustawiona wartość LeftMinimal, więc tylko przycisk menu jest wyświetlany niezależnie od szerokości okna.
adaptacyjnego zachowania
NavigationView z ustawieniem PaneDisplayMode na LeftMinimal
<NavigationView PaneDisplayMode="LeftMinimal" />
Jak opisano wcześniej w sekcji Tryby wyświetlania, można ustawić okienko, aby było zawsze na wierzchu, zawsze rozwinięte, zawsze kompaktowe lub zawsze minimalne. Tryby wyświetlania można również zarządzać samodzielnie w kodzie aplikacji. Przykład tego można znaleźć w następnej sekcji.
Nawigacja u góry do lewej
Kiedy korzystasz z górnej nawigacji w aplikacji, elementy nawigacyjne zwijają się do menu dodatkowego, gdy zmniejsza się szerokość okna. Gdy okno aplikacji jest wąskie, może zapewnić lepsze doświadczenie użytkownika, przełączając tryb wyświetlania panelu z Top na nawigację LeftMinimal, zamiast pozwalać, aby wszystkie elementy zwijały się do menu przepełnienia.
Zalecamy używanie górnej nawigacji w dużych rozmiarach okien i nawigacji po lewej stronie w małych rozmiarach okien, gdy:
- Masz zestaw równie ważnych kategorii nawigacji najwyższego poziomu, które mają być wyświetlane razem. Jeśli jedna z kategorii w tym zestawie nie mieści się na ekranie, zwijasz nawigację z lewej strony, żeby zapewnić im równe znaczenie.
- Chcesz zachować jak najwięcej miejsca na zawartość w małych rozmiarach okien.
W tym przykładzie pokazano, jak używać właściwości VisualStateManager i AdaptiveTrigger.MinWindowWidth , aby przełączać się między nawigacją Top i LeftMinimal .
<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>
Wskazówka
W przypadku korzystania z funkcji AdaptiveTrigger.MinWindowWidth stan wizualizacji jest wyzwalany, gdy okno jest szersze niż określona minimalna szerokość. Oznacza to, że domyślny kod XAML definiuje wąskie okno, a element VisualState definiuje modyfikacje stosowane w przypadku szerszego okna. Domyślny element PaneDisplayMode dla elementu NavigationView to Auto, dlatego gdy szerokość okna jest mniejsza lub równa CompactModeThresholdWidth, nawigacja jest używana LeftMinimal. Gdy okno staje się szersze, VisualState zastępuje wartość domyślną, a używana jest nawigacja Top.
Navigation
Element NavigationView nie wykonuje żadnych zadań nawigacji automatycznie. Gdy użytkownik stuknie element nawigacyjny, NavigationView wyświetla ten element jako wybrany i zgłasza zdarzenie ItemInvoked. Jeśli naciśnięcie spowoduje wybranie nowego elementu, zostanie również zgłoszone zdarzenie SelectionChanged.
Możesz obsłużyć dowolne z tych zdarzeń, aby wykonywać zadania związane z potrzebną nawigacją. Który z nich należy obsłużyć, zależy od zachowania aplikacji. Zazwyczaj przechodzisz do żądanej strony i aktualizujesz nagłówek NavigationView w odpowiedzi na te zdarzenia.
- Zdarzenie ItemInvoked jest wywoływane za każdym razem, gdy użytkownik stuknie element nawigacyjny, nawet jeśli został już wybrany. (Element można również wywołać za pomocą równoważnej akcji, używając myszy, klawiatury lub innych danych wejściowych. Aby uzyskać więcej informacji, zobacz Input and interactions.) Jeśli nawigujesz w procedurze obsługi `ItemInvoked`, to domyślnie strona zostanie ponownie załadowana, a do stosu nawigacji zostanie dodany duplikat wpisu. Jeśli nawigujesz po wywołaniu elementu, nie należy zezwalać na ponowne ładowanie strony lub upewnij się, że zduplikowany wpis nie zostanie utworzony w stosie nawigacyjnym po ponownym załadowaniu strony. (Zobacz przykłady kodu).
- Funkcja SelectionChanged może być wywoływana przez użytkownika wywołującego element, który nie jest aktualnie zaznaczony, lub programowo zmieniając wybrany element. Jeśli zmiana wyboru wystąpi, ponieważ użytkownik wywołał element, zdarzenie ItemInvoked następuje najpierw. Jeśli zmiana wyboru jest programowa, element ItemInvoked nie jest wywoływany.
Wszystkie elementy nawigacji są częścią tego samego modelu wyboru, niezależnie od tego, czy są one częścią MenuItems , czy FooterMenuItems. Jednocześnie można wybrać tylko jeden element nawigacji.
Nawigacja wstecz
NavigationView zawiera wbudowany w sobie przycisk Wstecz; ale podobnie jak w przypadku nawigacji do przodu, nie wykonuje automatycznej nawigacji wstecz. Gdy użytkownik naciśnie przycisk Wstecz, zostanie wywołane zdarzenie BackRequested. Obsługujesz to zdarzenie, aby wykonać nawigację wstecz. Aby uzyskać więcej informacji i przykładów kodu, zobacz Historia nawigacji i nawigacja wstecz.
W trybie Minimal lub Compact, NavigationView Pane jest otwarte jako menu wysuwane. W takim przypadku kliknięcie przycisku Wstecz spowoduje zamknięcie Pane i wywołanie zdarzenia PaneClosing.
Możesz ukryć lub wyłączyć przycisk Wstecz, ustawiając następujące właściwości:
-
IsBackButtonVisible: służy do pokazywania i ukrywania przycisku Wstecz. Ta właściwość przyjmuje wartość z wyliczenia NavigationViewBackButtonVisible i jest ustawiona domyślnie na
Auto. Po zwinięciu przycisku nie jest zarezerwowane żadne miejsce w układzie. -
IsBackEnabled: użyj polecenia, aby włączyć lub wyłączyć przycisk Wstecz. Możesz powiązać dane tej właściwości z właściwością CanGoBack ramki nawigacji.
BackRequested nie jest zgłaszana, jeśli
IsBackEnabledjestfalse.
przycisk 
Przycisk Wstecz w okienku nawigacji po lewej stronie
przycisk 
Przycisk Wstecz w górnym okienku nawigacji
Przykład kodu
W tym przykładzie pokazano, jak można używać elementu NavigationView zarówno z górnym okienkiem nawigacji w dużych rozmiarach okien, jak i lewym okienkiem nawigacji w małych rozmiarach okien. Można go dostosować do nawigacji tylko po lewej stronie, usuwając górne ustawienia nawigacji w VisualStateManager.
W tym przykładzie przedstawiono typowy sposób konfigurowania danych nawigacji, które będą działać w wielu scenariuszach. W tym przykładzie najpierw przechowujesz (w tagu NavigationViewItem) pełną nazwę strony, do której chcesz nawigować. W procedurze obsługi zdarzeń należy rozpakować tę wartość, przekształcić ją w obiekt typ(C#) lub Windows::UI::Xaml::Interop::TypeName(C++/WinRT) i użyj tego do nawigacji do strony docelowej. Umożliwia to utworzenie testów jednostkowych w celu potwierdzenia, że wartości wewnątrz tagów są prawidłowego typu. (Zobacz także pakowanie i rozpakowywanie wartości jako IInspectable z użyciem C++/WinRT). Pokazano również, jak zaimplementować nawigację wsteczną za pomocą przycisku wstecznego NavigationView.
W tym kodzie przyjęto założenie, że aplikacja zawiera strony o następujących nazwach, do których należy przejść: HomePage, AppsPage, GamesPage, MusicPage, MyContentPage i SettingsPage. Kod dla tych stron nie jest wyświetlany.
<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=""/>
</NavigationViewItem.Icon>
</NavigationViewItem>
<NavigationViewItem Tag="NavigationViewDemo.GamesPage" Content="Games">
<NavigationViewItem.Icon>
<FontIcon Glyph=""/>
</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());
}
}
}
}
}
}
}
Nawigacja hierarchiczna
Niektóre aplikacje mogą mieć bardziej złożoną strukturę hierarchiczną, która wymaga więcej niż tylko płaskiej listy elementów nawigacji. Możesz użyć elementów nawigacji najwyższego poziomu do wyświetlania kategorii stron, przy czym elementy podrzędne wyświetlają strony szczegółowe. Jest to również przydatne, jeśli masz strony w stylu centrum, które łączą się tylko z innymi stronami. W takich przypadkach należy utworzyć hierarchiczny element NavigationView.
Aby wyświetlić hierarchiczną listę zagnieżdżonych elementów nawigacji w okienku, użyj właściwości MenuItems lub MenuItemsSource właściwości NavigationViewItem. Każdy element NavigationViewItem może zawierać inne elementy NavigationViewItem oraz elementy organizacyjne, takie jak nagłówki elementów i separatory. Aby wyświetlić listę hierarchiczną przy użyciu MenuItemsSource, ustaw ItemTemplate jako NavigationViewItem i powiąż jego właściwość MenuItemsSource z następnym poziomem hierarchii.
Mimo że element NavigationViewItem może zawierać dowolną liczbę poziomów zagnieżdżonych, zalecamy utrzymywanie płytkiej hierarchii nawigacji aplikacji. Uważamy, że dwa poziomy są idealne do użyteczności i zrozumienia.
Element NavigationView pokazuje hierarchię w trybach wyświetlania paneli Top, Lefti LeftCompact. Oto, jak wygląda rozwinięte poddrzewo w każdym trybie wyświetlania okienka:
Dodawanie hierarchii elementów w znakowaniu
W tym przykładzie pokazano, jak zadeklarować hierarchiczną nawigację aplikacji w kodzie znaczników XAML.
<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>
Dodawanie hierarchii elementów przy użyciu powiązania danych
Dodawanie hierarchii elementów menu do elementu NavigationView według
- powiązanie właściwości MenuItemsSource z danymi hierarchicznymi
- definiowanie szablonu elementu jako NavigationViewMenuItem, z jego zawartością ustawioną jako etykieta elementu menu oraz z właściwością MenuItemsSource powiązaną z następnym poziomem hierarchii
W tym przykładzie przedstawiono również zdarzenia Rozszerzanie i zwinięte . Te zdarzenia są wywoływane dla elementu menu z dziećmi.
<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);
}
}
Selekcja
Domyślnie dowolny element może zawierać dzieci, być wywoływany lub wybierany.
Jeśli udostępniasz użytkownikom hierarchiczne drzewo opcji nawigacji, możesz zdecydować się, aby elementy nadrzędne nie mogły być wybierane, na przykład gdy aplikacja nie ma strony docelowej skojarzonej z tym elementem nadrzędnym. Jeśli elementy nadrzędne można wybrać, zaleca się użycie trybów wyświetlania Left-Expanded lub górnego okienka. Tryb LeftCompact spowoduje, że użytkownik będzie musiał przejść do elementu nadrzędnego, aby otworzyć poddrzewo za każdym razem, gdy tryb ten jest wywoływany.
Wybrane elementy będą wyświetlać wskaźniki wyboru wzdłuż swojej lewej krawędzi w trybie lewym lub wzdłuż dolnej krawędzi w trybie górnym. Poniżej przedstawiono kontrolki NavigationView w trybie po lewej stronie i u góry, w którym zaznaczono element nadrzędny.
Wybrany element może nie zawsze pozostać widoczny. Jeśli wybrano element podrzędny w zwiniętym/niewzrosłym poddrzewie, ich pierwszy widoczny obiekt nadrzędny będzie wyświetlany jako wybrany. Wskaźnik zaznaczenia zostanie przeniesiony z powrotem do wybranego elementu, jeśli/po rozwinięciu podzadrzewa.
Na przykład — na powyższej ilustracji użytkownik może wybrać element Kalendarz, a następnie zwinąć jego poddrzewo. W takim przypadku wskaźnik wyboru będzie wyświetlany pod elementem Konto, ponieważ Konto jest pierwszym widocznym przodkiem Kalendarza. Wskaźnik zaznaczenia powróci do elementu Kalendarz, gdy użytkownik ponownie rozszerza poddrzewo.
Cały element NavigationView będzie pokazywał nie więcej niż jeden wskaźnik wyboru.
W trybach Górny i Lewy, kliknięcie strzałek w elementach NavigationView spowoduje rozwinięcie lub zwinięcie poddrzewa. Kliknięcie lub naciśnięcie w innym miejscu na elemencie NavigationViewItem spowoduje wyzwolenie zdarzenia ItemInvoked, a także zwinięcie lub rozwinięcie poddrzewa.
Aby zapobiec wyświetlaniu wskaźnika wyboru podczas wywoływania elementu, ustaw jego właściwość SelectsOnInvoked na False, jak pokazano poniżej:
<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);
}
...
Klawiaturowanie w hierarchicznym widoku nawigacji
Użytkownicy mogą przenosić fokus wokół elementu NavigationView przy użyciu klawiatury. Klawisze strzałek umożliwiają dostęp do "nawigacji wewnętrznej" w okienku i podążaj za interakcjami podanymi w widoku drzewa . Akcje kluczowe zmieniają się podczas nawigowania po widoku Nawigacji lub w menu wysuwanym, które jest wyświetlane w trybach HierarchicalNavigationView u góry i lewej. Poniżej przedstawiono konkretne akcje, które każdy klucz może wykonać w hierarchicznym widoku nawigacji:
| Key | W trybie lewym | W trybie najwyższym | Okienko wysuwane |
|---|---|---|---|
| Up | Przenosi fokus do elementu bezpośrednio nad elementem, który jest obecnie w centrum uwagi. | Nic nie robi. | Przenosi fokus do elementu bezpośrednio nad elementem, który jest obecnie w centrum uwagi. |
| W dół | Przenosi fokus bezpośrednio poniżej elementu aktualnie w fokusie.* | Nic nie robi. | Przenosi fokus bezpośrednio poniżej elementu aktualnie w fokusie.* |
| Prawo | Nic nie robi. | Przenosi fokus do elementu bezpośrednio po prawej stronie elementu aktualnie w fokusie. | Nic nie robi. |
| Lewo | Nic nie robi. | Przenosi fokus do elementu bezpośrednio po lewej stronie elementu aktualnie w fokusie. | Nic nie robi. |
| Spacja/Enter | Jeśli element posiada podległe elementy, rozwija/zwija je, nie zmieniając fokusa. | Jeśli element ma elementy podrzędne, rozwija je w wysuwanym menu i umieszcza fokus na pierwszym elemencie. | Wywołuje/wybiera element i zamyka okno wysuwane. |
| Esc | Nic nie robi. | Nic nie robi. | Zamyka okno wysuwane. |
Spacja lub enter zawsze wywołuje/wybiera element.
*Należy pamiętać, że elementy nie muszą być wizualnie sąsiadujące, fokus zostanie przeniesiony z ostatniego elementu na liście okienka do elementu ustawień.
Dostosowywanie elementu NavigationView
Tła okienek
Domyślnie okienko NavigationView używa innego tła w zależności od trybu wyświetlania:
- okienko jest stałym szarym kolorem po rozwinięciu po lewej stronie, obok zawartości (w trybie po lewej stronie).
- okienko używa akrylu w aplikacji, gdy jest otwarty jako nakładka na wierzchu zawartości (w trybie Top, Minimal lub Compact).
Aby zmodyfikować tło okienka, możesz zastąpić zasoby motywu XAML używane do renderowania tła w każdym trybie. (Ta technika jest używana zamiast pojedynczej właściwości PaneBackground, aby obsługiwać różne tła dla różnych trybów wyświetlania.)
W tej tabeli przedstawiono, który zasób motywu jest używany w każdym trybie wyświetlania.
| Tryb wyświetlania | Zasób motywu |
|---|---|
| Lewo | TłoRozszerzanegoPaneluWidokuNawigacji |
| LewoKompaktowy LeftMinimal |
DomyślneTłoPaskaNawigacji |
| Do góry | TłoGórnegoPaneluNawigacji |
W tym przykładzie pokazano, jak przesłonić zasoby motywu w pliku App.xaml. Podczas zastępowania zasobów motywu zawsze należy przynajmniej podać słowniki zasobów "Default" i "HighContrast", a także słowniki dla zasobów "Jasny" lub "Ciemny", w razie potrzeby. Aby uzyskać więcej informacji, zobacz ResourceDictionary.ThemeDictionaries.
Ważne
Ten kod pokazuje, jak używać winUI 2 wersji AkrylBrush. Jeśli zamiast tego używasz wersji platformy AcrylicBrush, minimalną wersją projektu aplikacji musi być zestaw SDK 16299 lub nowszy. Aby użyć wersji platformy, usuń wszystkie odwołania do 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>
Górne białe miejsce
Właściwość
IsTitleBarAutoPaddingEnabledwymaga interfejsu WinUI 2.2 lub nowszego.
Niektóre aplikacje decydują się dostosować pasek tytułu okna, co potencjalnie rozszerza zawartość aplikacji na obszar paska tytułu. Gdy Element NavigationView jest elementem głównym w aplikacjach, które rozszerzają się na pasek tytułu przy użyciu ExtendViewIntoTitleBar api, kontrolka automatycznie dostosowuje położenie swoich elementów interaktywnych, aby zapobiec nakładaniu się regionu przeciąganego.
Jeśli aplikacja określa region przeciągany przez wywołanie metody Window.SetTitleBar i wolisz mieć przyciski wstecz i menu przesuwać bliżej górnej części okna aplikacji, ustaw IsTitleBarAutoPaddingEnabled na false.
<muxc:NavigationView x:Name="NavView" IsTitleBarAutoPaddingEnabled="False">
Uwagi
Aby lepiej dostosować położenie obszaru nagłówka elementu NavigationView, przesłoń zasób motywu XAML NavigationViewHeaderMargin, na przykład w zasobach strony.
<Page.Resources>
<Thickness x:Key="NavigationViewHeaderMargin">12,0</Thickness>
</Page.Resources>
Ten zasób motywu modyfikuje margines wokół NavigationView.Header.
UwP i WinUI 2
Ważne
Informacje i przykłady w tym artykule są zoptymalizowane dla aplikacji korzystających z Windows App SDK oraz WinUI 3, ale generalnie mają zastosowanie także w aplikacjach UWP używających WinUI 2. Zobacz dokumentację interfejsu API platformy UWP, aby uzyskać informacje i przykłady dotyczące platformy.
Ta sekcja zawiera informacje potrzebne do używania kontrolki w aplikacji platformy UWP lub WinUI 2.
Kontrolka NavigationView dla aplikacji platformy UWP jest dołączona w ramach interfejsu WinUI 2. Aby uzyskać więcej informacji, w tym instrukcje dotyczące instalacji, zobacz WinUI 2. Interfejsy API dla tej kontrolki istnieją zarówno w przestrzeniach nazw Windows.UI.Xaml.Controls , jak i Microsoft.UI.Xaml.Controls .
- interfejsy API platformy UWP:Windows.UI.Xaml.Controls.NavigationView, klasa
- WinUI 2 API :klasa Microsoft.UI.Xaml.Controls.NavigationView
-
Otwórz aplikację WinUI 2 Gallery i zobacz element NavigationView w działaniu. Aplikacja z galerii
WinUI 2 zawiera interaktywne przykłady większości kontrolek, funkcji i funkcji winUI 2. Pobierz aplikację ze Sklepu Microsoft lub pobierz kod źródłowy w witrynie GitHub.
Zalecamy użycie najnowszego interfejsu WinUI 2 , aby uzyskać najbardziej aktualne style, szablony i funkcje dla wszystkich kontrolek. Niektóre funkcje elementu NavigationView, takie jak nawigacja górna i hierarchiczna , wymagają systemu Windows 10, wersja 1809 (zestaw SDK 17763) lub nowszy albo WinUI 2.
Aby użyć kodu z tego artykułu w WinUI 2, użyj aliasu w XAML (używamy muxc), aby reprezentować API Biblioteki Interfejsu Użytkownika Windows, które są uwzględnione w Twoim projekcie. Aby uzyskać więcej informacji, zobacz Wprowadzenie do interfejsu WinUI 2 .
xmlns:muxc="using:Microsoft.UI.Xaml.Controls"
<muxc:NavigationView />
Tematy pokrewne
- klasy
NavigationView - lista/szczegóły
- Podstawowe informacje o nawigacji
- Fluent Design — omówienie
Windows developer