Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Ovládací prvek NavigationView poskytuje navigaci na nejvyšší úrovni pro vaši aplikaci. Přizpůsobí se různým velikostem obrazovky a podporuje navigační styly jak horní, tak levé.
NavigationView podporuje horní i levé navigační podokno nebo nabídku.
Je to správná kontrola?
NavigationView je adaptivní ovládací prvek navigace, který funguje dobře pro:
- Poskytuje konzistentní navigační prostředí v celé aplikaci.
- Zachování místa na obrazovce v menších oknech.
- Uspořádání přístupu k mnoha kategoriím navigace
Další vzory navigace najdete v tématu Základy návrhu navigace.
Vytvoření navigačního zobrazení
- důležitá rozhraní API:třída NavigationView
Aplikace WinUI 3 Gallery obsahuje interaktivní příklady většiny ovládacích prvků, vlastností a funkcionality WinUI 3. Získání aplikace z Microsoft Storu nebo získání zdrojového kódu na GitHubu
Tento příklad ukazuje, jak vytvořit jednoduché navigační zobrazení v 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>
Režimy zobrazení
Vlastnost PaneDisplayMode můžete použít ke konfiguraci různých stylů navigace nebo režimů zobrazení pro NavigationView.
Vrchol
Panel je umístěný nad obsahem.PaneDisplayMode="Top"
Doporučujeme horní navigaci , když:
- Máte 5 nebo méně kategorií navigace na nejvyšší úrovni, které jsou stejně důležité. Jakékoliv další kategorie navigace nejvyšší úrovně, které končí v rozevírací nabídce, jsou považovány za méně důležité.
- Musíte zobrazit všechny možnosti navigace na obrazovce.
- Chcete více místa pro obsah aplikace.
- Ikony nemohou jasně popsat navigační kategorie vaší aplikace.
Vlevo
Podokno je rozbaleno a umístěno nalevo od obsahu.PaneDisplayMode="Left"
Doporučujeme navigaci vlevo pomocí , když:
- Máte 5–10 stejně důležitých kategorií navigace na nejvyšší úrovni.
- Chcete, aby navigační kategorie byly velmi výrazné, s menším místem pro ostatní obsah aplikace.
LeftCompact
V panelu se zobrazují pouze ikony, dokud není otevřený, a je umístěn nalevo od obsahu. Po otevření podokno překryje obsah.PaneDisplayMode="LeftCompact"
Levý-Minimal
Je zobrazeno pouze tlačítko nabídky, dokud není podokno otevřeno. Po otevření překryjí podokno levou stranu obsahu.PaneDisplayMode="LeftMinimal"
Auto
Ve výchozím nastavení je PaneDisplayMode nastaven na Auto. V Auto režimu se navigationView přizpůsobí mezi LeftMinimal, když je okno úzké, LeftCompacta pak Left, jak se okno rozšiřuje. Další informace najdete v části adaptivního chování .
Výchozí adaptivní chování NavigationView
Anatomie
Tyto obrázky znázorňují rozložení oblastí podokna, záhlaví a obsahu ovládacího prvku při konfiguraci pro navigaci buď s horním , nebo levým panelem.
rozložení horní navigace
Levé navigační rozložení
Okno
Vlastnost PaneDisplayMode můžete použít k umístění podokna nad obsah nebo nalevo od obsahu.
Podokno NavigationView může obsahovat:
- NavigationViewItem objekty. Navigační položky pro navigaci na konkrétní stránky
- *NavigationViewItemSeparator* objekty. Oddělovače pro seskupování navigačních položek Nastavte vlastnost Neprůhlednost na hodnotu 0, aby se oddělovač vykreslil jako mezera.
- NavigationViewItemHeader objekty. Záhlaví pro označování skupin položek
- Volitelný ovládací prvek AutoSuggestBox , který umožňuje vyhledávání na úrovni aplikace. Přiřaďte ovládací prvek NavigationView.AutoSuggestBox vlastnost.
- Vstupní bod pro volitelná nastavení aplikace . Chcete-li skrýt položku nastavení, nastavte vlastnost IsSettingsVisible na hodnotu
false.
Levé podokno obsahuje také:
- Tlačítko nabídky pro přepnutí otevřeného a uzavřeného podokna Ve větších oknech aplikací, když je podokno otevřené, můžete toto tlačítko skrýt pomocí Vlastnosti IsPaneToggleButtonVisible .
NavigationView má tlačítko zpět umístěné v levém horním rohu podokna. Automaticky ale nezpracuje zpětnou navigaci ani nepřidá obsah do zadního zásobníku. Chcete-li povolit zpětnou navigaci, viz část zpětná navigace.
Tady je podrobná anatomie podokna pro pozice horního a levého podokna.
Horní navigační podokno
- Headers
- Navigační položky
- Oddělovače
- AutoSuggestBox (volitelné)
- Tlačítko Nastavení (volitelné)
Levé navigační podokno
- Tlačítko nabídky
- Navigační položky
- Oddělovače
- Headers
- AutoSuggestBox (volitelné)
- Tlačítko Nastavení (volitelné)
Položky nabídky zápatí
FooterMenuItems můžete použít k umístění navigačních položek na konec navigačního podokna, kontrastované s vlastností MenuItems, která umístí položky na začátek podokna.
Položky zápatí nabídky se ve výchozím nastavení zobrazí před položkou Settings. Položku Settings lze přesto přepnout pomocí vlastnosti IsSettingsVisible.
Do menu položky zápatí by měly být umístěny pouze navigační položky – jakýkoli jiný obsah, který musí být zarovnán do zápatí podokna, by se měl umístit do PaneFooter.
Příklad přidání FooterMenuItems do navigationView, viz FooterMenuItems třída.
Následující obrázek ukazuje NavigationView s účet, nákupní košíka nápověda navigačními položkami v dolní nabídce.
Zápatí podokna
Volný obsah můžete umístit do zápatí podokna přidáním do vlastnosti PaneFooter.
zápatí horního podokna
zápatí levého podokna
Název a záhlaví panelu
Do oblasti záhlaví podokna můžete umístit textový obsah nastavením vlastnosti PaneTitle . Vezme řetězec a zobrazí text vedle tlačítka nabídky.
Pokud chcete přidat netextový obsah, například obrázek nebo logo, můžete do záhlaví podokna umístit libovolný prvek tak, že ho přidáte do vlastnosti PaneHeader .
Pokud je nastaveno PaneTitle i PaneHeader, obsah je vodorovně vedle tlačítka nabídky, přičemž PaneTitle je nejblíže tlačítku nabídky.
záhlaví horního panelu
záhlaví levého podokna
Obsah podokna
Obsah volného formuláře můžete umístit do podokna přidáním do Vlastnosti PaneCustomContent .
Vlastní obsah horního podokna
vlastní vlastního obsahu v levém podokně
Header
Název stránky můžete přidat nastavením vlastnosti Záhlaví .
záhlaví
Oblast záhlaví je svisle zarovnána s navigačním tlačítkem na pozici levého panelu a leží pod panelem v horní pozici. Má pevnou výšku 52 pixelů. Jejím účelem je uchovávat název stránky vybrané navigační kategorie. Záhlaví je připevněno k horní části stránky a funguje jako bod pro oříznutí posouváním obsahu.
Záhlaví je viditelné pokaždé, když je NavigationView v Minimal režimu zobrazení. Můžete se rozhodnout skrýt záhlaví v jiných režimech, které se používají při větší šířce okna. Pokud chcete záhlaví skrýt, nastavte vlastnost AlwaysShowHeader na falsehodnotu .
Content
NavigationView obsah
V oblasti obsahu se zobrazuje většina informací pro vybranou kategorii navigace.
Doporučujeme pro oblast obsahu použít 12px okraje, když je NavigationView v režimu Minimal, a jinak 24px okraje.
Adaptivní chování
Ve výchozím nastavení navigationView automaticky změní režim zobrazení na základě množství dostupného místa na obrazovce. Vlastnosti CompactModeThresholdWidth a ExpandedModeThresholdWidth určují zarážky, při kterých se změní režim zobrazení. Tyto hodnoty můžete upravit tak, aby se přizpůsobilo chování režimu adaptivního zobrazení.
Výchozí
Pokud je PaneDisplayMode nastaven na výchozí hodnotu Auto, adaptivní chování je zobrazit:
- Rozbalené levé podokno při šířkách oken 1008 pixelů nebo větších.
- Levé navigační podokno pouze s ikonami (
LeftCompact) při středních šířkách oken (641px až 1007px). - Pouze tlačítko nabídky (
LeftMinimal) na malých šířkách oken (640 pixelů nebo méně).
Další informace o velikostech oken pro adaptivní chování najdete v tématu Velikosti obrazovky a zarážky.
Výchozí adaptivní chování NavigationView
Minimální
Druhým běžným adaptivním vzorem je použití rozšířeného levého podokna na velkých šířkách oken a pouze tlačítko nabídky na střední i malé šířce okna.
Doporučujeme, když:
- Chcete více místa pro obsah aplikace na menších šířkách okna.
- Vaše navigační kategorie nemohou být jasně reprezentovány ikonami.
navigationView "minimální" adaptivní chování
Chcete-li toto chování nakonfigurovat, nastavte CompactModeThresholdWidth na šířku, při které chcete podokno sbalit. Tady se změní z výchozí hodnoty 640 na 1007. Měli byste také nastavit ExpandedModeThresholdWidth, abyste zajistili, že hodnoty nejsou v konfliktu.
<NavigationView CompactModeThresholdWidth="1007" ExpandedModeThresholdWidth="1007"/>
kompaktní
Třetím běžným adaptivním vzorem je použití rozšířeného levého podokna při velkých šířkách oken a kompaktního levého navigačního panelu pouze s ikonami při středních a malých šířkách oken.
Doporučujeme, když:
- Je důležité vždy zobrazovat všechny možnosti navigace na obrazovce.
- Vaše navigační kategorie můžou být jasně reprezentovány ikonami.
"kompaktní" adaptivní chování navigačního zobrazení
Chcete-li toto chování nakonfigurovat, nastavte CompactModeThresholdWidth na hodnotu 0.
<NavigationView CompactModeThresholdWidth="0"/>
Žádné adaptivní chování
Chcete-li zakázat automatické adaptivní chování, nastavte PaneDisplayMode na jinou hodnotu než Auto. Tady je nastavená na LeftMinimal, takže se zobrazí pouze tlačítko nabídky bez ohledu na šířku okna.
NavigationView s PaneDisplayMode nastaveným na LeftMinimal
<NavigationView PaneDisplayMode="LeftMinimal" />
Jak je popsáno dříve v oddílu režimy zobrazení, můžete nastavit, aby se podokno zobrazovalo vždy nahoře, vždy rozbalené, vždy kompaktní nebo vždy minimální. Režimy zobrazení můžete spravovat také sami v kódu aplikace. Příklad je uvedený v další části.
Navigace v levém horním rohu
Když v aplikaci používáte horní navigaci, navigační položky se sbalí do rozbalovací nabídky, když se zmenší šířka okna. Když je okno vaší aplikace úzké, může poskytnout lepší uživatelský zážitek, když přepnete PaneDisplayMode z Top na navigaci LeftMinimal, než když necháte všechny položky sbalit do nabídky přetečení.
Doporučujeme použít horní navigaci u velkých velikostí oken a levou navigaci v malých velikostech oken v následujících případech:
- Máte sadu stejně důležitých navigačních kategorií nejvyšší úrovně, které se mají zobrazit společně. Pokud se jedna z těchto kategorií nevejde na obrazovku, přepnete navigaci doleva, aby měly stejnou důležitost.
- V malých velikostech oken chcete zachovat co nejvíce místa na obsahu.
Tento příklad ukazuje, jak použít VisualStateManager a vlastnost AdaptiveTrigger.MinWindowWidth pro přepínání mezi Top a LeftMinimal navigací.
<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>
Návod
Pokud použijete AdaptiveTrigger.MinWindowWidth, vizuální stav se aktivuje, když je okno širší než zadaná minimální šířka. To znamená, že výchozí XAML definuje úzké okno a VisualState definuje úpravy, které se použijí, když se okno rozšíří. Výchozí režim zobrazení panelu (PaneDisplayMode) pro NavigationView je Auto, takže když je šířka okna menší nebo rovna CompactModeThresholdWidth, použije se navigace LeftMinimal. Když se okno rozšíří, VisualState přepíše výchozí hodnotu a Top použije se navigace.
Navigace
NavigationView neprovádí žádné navigační úlohy automaticky. Když uživatel klepne na navigační položku, NavigationView zobrazí tuto položku jako vybranou a vyvolá ItemInvoked událost. Pokud klepnutí způsobí výběr nové položky, vyvolá se také událost SelectionChanged .
K provádění úloh souvisejících s požadovanou navigaci můžete zpracovat kteroukoli událost. Který z nich byste měli zpracovat, závisí na požadovaném chování aplikace. Obvykle přejdete na požadovanou stránku a aktualizujete záhlaví NavigationView v reakci na tyto události.
- ItemInvoked je vyvolána pokaždé, když uživatel klepne na navigační položku, i když už je vybraná. (Položku lze vyvolat také ekvivalentní akcí pomocí myši, klávesnice nebo jiného vstupu. Další informace najdete v tématu Vstupy a interakce.) Pokud ve výchozím nastavení přejdete do obslužné rutiny ItemInvolat, stránka se znovu načte a do zásobníku navigace se přidá duplicitní položka. Pokud při vyvolání položky přecházíte na jinou stránku, měli byste zakázat opětovné načtení stránky nebo zajistit, aby se při opětovném načtení nevytvořila duplicitní položka v historii navigace. (Viz příklady kódu.)
- SelectionChanged může být vyvolán uživatelem, který aktivuje položku, která není aktuálně vybraná, nebo programovou změnou vybrané položky. Pokud dojde ke změně výběru, protože uživatel vyvolal položku, dojde nejprve k události ItemInvolat. Pokud je změna výběru programatická, událost ItemInvoked není vyvolána.
Všechny navigační položky jsou součástí stejného modelu výběru, ať už jsou součástí MenuItems nebo FooterMenuItems. Najednou je možné vybrat pouze jednu navigační položku.
Zpětná navigace
NavigationView má integrované tlačítko zpět; ale stejně jako u navigace vpřed se neprovádí zpětná navigace automaticky. Když uživatel klepne na tlačítko Zpět, vyvolá se událost BackRequested. Tuto událost zpracujete, abyste provedli zpětnou navigaci. Další informace a příklady kódu najdete v tématu Historie navigace a zpětná navigace.
V Minimal nebo Compact režimu je Pane NavigationView otevřený jako informační panel. V tomto případě kliknutím na tlačítko Zpět zavřete Pane a místo toho vyvoláte událost PaneClosing.
Tlačítko Zpět můžete skrýt nebo zakázat nastavením těchto vlastností:
-
IsBackButtonVisible: slouží k zobrazení a skrytí tlačítka Zpět. Tato vlastnost přebírá hodnotu NavigationViewBackButtonVisible výčtu a je nastavena na
Autove výchozím nastavení. Když je tlačítko sbalené, není pro něj v rozložení vyhrazeno žádné místo. -
IsBackEnabled: Slouží k povolení nebo zakázání tlačítka Zpět. Tuto vlastnost můžete svázat s vlastností CanGoBack navigačního rámce.
BackRequested není vyvolán, pokud je
IsBackEnabledfalse.
Tlačítko Zpět v levém navigačním podokně
Tlačítko Zpět v horním navigačním podokně
Příklad kódu
Tento příklad ukazuje, jak můžete použít NavigationView s horním navigačním podoknem ve velkých velikostech oken i v levém navigačním podokně v malých velikostech oken. Navigaci lze přizpůsobit pouze vlevo odebráním nastavení horní navigace ve VisualStateManager.
Příklad ukazuje běžný způsob, jak nastavit navigační data, která budou fungovat pro mnoho scénářů. V tomto příkladu nejprve uložíte (ve značce NavigationViewItem) úplný název stránky, do které chcete přejít. V obslužné rutině události rozbalíte tuto hodnotu, převedete ji na objekt Type(C#) nebo Windows::UI::Xaml::Interop::TypeName(C++/WinRT) a použijete ji k přechodu na cílovou stránku. Díky tomu můžete vytvářet jednotkové testy, abyste potvrdili, že hodnoty uvnitř značek jsou platného typu. (Viz také Boxing a unboxing hodnot na IInspectable s C++/WinRT). Také ukazuje, jak implementovat zpětnou navigaci pomocí tlačítka zpět navigačního zobrazení NavigationView.
Tento kód předpokládá, že aplikace obsahuje stránky s následujícími názvy, na které přejdete: HomePage, AppsPage, GamesPage, MusicPage, MyContentPage a SettingsPage. Kód pro tyto stránky se nezobrazuje.
<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());
}
}
}
}
}
}
}
Hierarchická navigace
Některé aplikace můžou mít složitější hierarchickou strukturu, která vyžaduje více než jen plochý seznam navigačních položek. K zobrazení kategorií stránek můžete použít navigační položky nejvyšší úrovně s podřízenými položkami, které zobrazují konkrétní stránky. Je také užitečné, pokud máte stránky ve stylu centra, které odkazují pouze na jiné stránky. Pro tyto druhy případů byste měli vytvořit hierarchický NavigationView.
Chcete-li zobrazit hierarchický seznam vnořených navigačních položek v podokně, použijte vlastnost MenuItems nebo MenuItemsSource objektu NavigationViewItem. Každý NavigationViewItem může obsahovat další NavigationViewItem a organizační prvky, jako jsou záhlaví položek a oddělovače. Chcete-li zobrazit hierarchický seznam při použití MenuItemsSource, nastavte ItemTemplate jako NavigationViewItem a jeho vlastnost MenuItemsSource navázat na další úroveň hierarchie.
I když NavigationViewItem může obsahovat libovolný počet vnořených úrovní, doporučujeme zachovat navigační hierarchii vaší aplikace v mělkém stavu. Věříme, že dvě úrovně jsou ideální pro použitelnost a porozumění.
NavigationView zobrazuje hierarchii v režimech zobrazení podokna Top, Lefta LeftCompact. Takto vypadá rozbalený podstrom v jednotlivých režimech zobrazení podokna:
Přidání hierarchie položek ve značkovacím jazyce
Tento příklad ukazuje, jak deklarovat hierarchickou navigaci v aplikaci v kódu 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>
Přidání hierarchie položek pomocí datové vazby
Přidejte hierarchii položek nabídky do NavigationView podle
- vytvoření vazby vlastnosti MenuItemsSource na hierarchická data
- definování šablony položky jako NavigationViewMenuItem, s Content nastaveno na popisek položky nabídky a vlastnost MenuItemsSource vázanou na další úroveň hierarchie
Tento příklad také ukazuje události Rozbalování a Sbalení. Tyto události jsou vyvolány pro položku nabídky s podřízený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);
}
}
Selection
Ve výchozím nastavení může každá položka obsahovat podřízené položky, být vyvolána nebo vybrána.
Když uživatelům poskytnete hierarchický strom možností navigace, můžete se rozhodnout, že nadřazené položky nebudou vybrány, například když vaše aplikace nemá přidruženou cílovou stránku přidruženou k této nadřazené položce. Pokud jsou nadřazené položky vybratelné, doporučujeme použít režim zobrazení Left-Expanded nebo horní panel. Režim LeftCompact způsobí, že uživatel přejde k nadřazené položce, aby při každém vyvolání otevřel podřízený podstrom.
Vybrané položky kreslí indikátory výběru podél levého okraje, když jsou v levém režimu, nebo podél dolního okraje, když jsou v horním režimu. Níže jsou navigační zobrazení v levém a horním režimu, kde je vybrána nadřazená položka.
Vybraná položka nemusí vždy zůstat viditelná. Pokud je vybráno dítě ve sbaleném nebo nesbaleném podstromu, zobrazí se jeho první viditelný předek jako vybraný. Indikátor výběru se přesune zpět na vybranou položku, pokud/když je dílčí strom rozbalen.
Například na obrázku výše může uživatel vybrat položku Kalendář a potom může sbalit její podstrom. V tomto případě by se indikátor výběru zobrazil pod položkou Účet, protože Účet je prvním viditelným nadřazeným prvkem kalendáře. Indikátor výběru se přesune zpět na položku Kalendáře, jakmile uživatel znovu rozbalí podstrom.
Celé navigační zobrazení nebude zobrazovat více než jeden indikátor výběru.
V obou režimech nahoře a vlevo kliknutím na šipky v NavigationViewItems rozbalíte nebo sbalíte podstrom. Kliknutím nebo klepnutím na jinde v NavigationViewItem se aktivuje událost ItemInvoked a také se sbalí nebo rozbalí podstrom.
Chcete-li zabránit zobrazení indikátoru výběru při vyvolání, nastavte jeho SelectsOnInvoked vlastnost na False, jak je znázorněno níže:
<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);
}
...
Klávesnice v hierarchickém navigačním zobrazení
Uživatelé mohou přesouvat zaměření po navigačním panelu pomocí klávesnice. Klávesy se šipkami v podokně zpřístupňují "vnitřní navigaci" a sledují interakce uvedené ve stromovém zobrazení . Klíčové akce se mění při procházení Navigačního zobrazení nebo jeho rozbalovací nabídky, která je zobrazena v režimech Top a Left-compact HierarchicalNavigationView. Níže jsou uvedené konkrétní akce, které může každý klíč provést v hierarchickém navigačním zobrazení:
| Key | V levém režimu | V horním režimu | V rozbalovacím menu |
|---|---|---|---|
| Up | Přesune fokus na položku přímo nad položkou, která je aktuálně v fokusu. | Nedělá nic. | Přesune fokus na položku přímo nad položkou, která je aktuálně v fokusu. |
| Dolů | Přesune fokus přímo pod položku, která je aktuálně fokus.* | Nedělá nic. | Přesune fokus přímo pod položku, která je aktuálně fokus.* |
| Správně | Nedělá nic. | Přesune fokus na položku přímo napravo od položky, která je aktuálně v fokusu. | Nedělá nic. |
| Vlevo | Nedělá nic. | Přesune zaměření na položku, která je přímo nalevo od aktuálního zaměření. | Nedělá nic. |
| Mezera/Enter | Pokud položka obsahuje podřízené položky, rozbalí nebo sbalí položku a nezmění zaostření. | Pokud položka obsahuje podřízené položky, rozbalí podřízené položky do informačního rámečku a umístí fokus na první položku v informačním rámečku. | Vyvolá nebo vybere položku a zavře rozbalovací nabídku. |
| Esc | Nedělá nic. | Nedělá nic. | Zavře informační oušku. |
Klávesa mezerníku nebo klávesa Enter vždy vyvolá nebo vybere položku.
*Všimněte si, že položky nemusí být vizuálně sousední, fokus se přesune z poslední položky v seznamu podokna na položku nastavení.
Přizpůsobení navigačního zobrazení
Pozadí podokna
Ve výchozím nastavení používá podokno NavigationView jiné pozadí v závislosti na režimu zobrazení:
- Když je podokno rozbaleno vlevo, vedle obsahu, je jednobarevné šedé (v levém režimu).
- Podokno používá v aplikaci akrylový efekt, když je otevřené jako překryvná vrstva nad obsahem (v režimu Top, Minimal nebo Compact).
Pokud chcete upravit pozadí podokna, můžete přepsat prostředky motivu XAML použité k vykreslení pozadí v každém režimu. (Tato technika se používá místo jedné vlastnosti PaneBackground k podpoře různých pozadí pro různé režimy zobrazení.)
Tato tabulka ukazuje, který zdroj motivu je používán v každém režimu zobrazení.
| Režim zobrazení | Zdroj tématu |
|---|---|
| Vlevo | PozadíNavigačníhoZobrazeníRozšířenéhoPanelu |
| LeftCompact Levý-Minimal |
VýchozíPozadíPaneluNavigace |
| Vrchol | Pozadí horního panelu zobrazení navigace |
Tento příklad ukazuje, jak přepsat prostředky tématu v App.xaml. Při předefinování prostředků motivu byste měli vždy poskytnout slovníky prostředků „Default“ a „HighContrast“ a také slovníky pro „Light“ nebo „Dark“ prostředky podle potřeby. Další informace naleznete v části ResourceDictionary.ThemeDictionaries.
Důležité
Tento kód ukazuje, jak používat WinUI 2 verzi AkrylBrush. Pokud místo toho používáte verzi platformy AkrylBrush, minimální verze projektu aplikace musí být SDK 16299 nebo vyšší. Chcete-li použít verzi platformy, odstraňte všechny odkazy na 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>
Horní prázdné místo
Vlastnost
IsTitleBarAutoPaddingEnabledvyžaduje WinUI 2.2 nebo novější.
Některé aplikace se rozhodnou přizpůsobit záhlaví okna, aby případně rozšířily obsah své aplikace do oblasti záhlaví. Pokud je NavigationView kořenovým prvkem v aplikacích, které se rozšiřují do záhlaví pomocí ExtendViewIntoTitleBar API, ovládací prvek automaticky upraví pozici svých interaktivních prvků, aby nedocházelo k překrývání s přetahovatelnou oblastí.
Pokud vaše aplikace určuje přetahovatelnou oblast voláním metody Window.SetTitleBar a chcete, aby tlačítka Zpět a Nabídka byla zobrazena blíž k horní části okna aplikace, nastavte IsTitleBarAutoPaddingEnabled na false.
<muxc:NavigationView x:Name="NavView" IsTitleBarAutoPaddingEnabled="False">
Poznámky
Pokud chcete dále upravit umístění oblasti záhlaví NavigationView, přepište NavigationViewHeaderMargin prostředek motivu XAML, například v prostředcích vaší stránky.
<Page.Resources>
<Thickness x:Key="NavigationViewHeaderMargin">12,0</Thickness>
</Page.Resources>
Tento prostředek motivu upraví okraj kolem NavigationView.Header.
Univerzální platforma Windows a WinUI 2
Důležité
Informace a příklady v tomto článku jsou optimalizované pro aplikace, které používají Windows App SDK a WinUI 3, ale obecně platí pro aplikace pro UPW, které používají WinUI 2. Informace o konkrétních platformách a příklady najdete v referenčních informacích k rozhraní API pro UPW.
Tato část obsahuje informace potřebné pro použití ovládacího prvku v aplikacích UWP nebo WinUI 2.
Ovládací prvek NavigationView pro aplikace pro UPW je součástí WinUI 2. Další informace, včetně pokynů k instalaci, najdete v tématu WinUI 2. Rozhraní API existují pro tento ovládací prvek v názvových oborech Windows.UI.Xaml.Controls a Microsoft.UI.Xaml.Controls.
- rozhraní API pro UWP :třída Windows.UI.Xaml.Controls.NavigationView
- Rozhraní API WinUI 2:třídy Microsoft.UI.Xaml.Controls.NavigationView
- Otevřete aplikaci Galerie WinUI 2 a podívejte se na navigationView v akci. Aplikace WinUI 2 Gallery obsahuje interaktivní ukázky většiny ovládacích prvků, funkcí a vlastností WinUI 2. Získejte aplikaci z Microsoft Storu nebo získejte zdrojový kód na GitHubu.
K získání nejnovějších stylů, šablon a funkcí pro všechny ovládací prvky doporučujeme použít nejnovější winUI 2 . Některé funkce NavigationView, jako je top a hierarchická navigace, vyžadují Windows 10 verze 1809 (SDK 17763) nebo novější nebo WinUI 2.
Pokud chcete použít kód v tomto článku s WinUI 2, použijte alias v JAZYCE XAML (používáme muxc) k reprezentaci rozhraní API knihovny uživatelského rozhraní Systému Windows, která jsou součástí vašeho projektu. Další informace najdete v tématu Začínáme s WinUI 2 .
xmlns:muxc="using:Microsoft.UI.Xaml.Controls"
<muxc:NavigationView />
Související témata
- třídy NavigationView
- Seznam/podrobnosti
- Základy navigace
- Přehled Fluent Design
Windows developer