本文參考了官方文檔以及提供的示例代碼(官方代碼貌似有點誤導,所以寫了這一篇,並且文末有GayHub代碼地址) 官方文檔發佈於20180806,說明NavigationView剛發佈了沒幾天,還在開發中,所以裡面的介面啥的隨時會變! 隨時會變! 隨時會變! ,用在你的項目之前,請需要做好充足的心理準備 ...
本文參考了官方文檔以及提供的示例代碼(官方代碼貌似有點誤導,所以寫了這一篇,並且文末有GayHub代碼地址)
官方文檔發佈於20180806,說明NavigationView剛發佈了沒幾天,還在開發中,所以裡面的介面啥的隨時會變! 隨時會變! 隨時會變! ,用在你的項目之前,請需要做好充足的心理準備。
不過他變任他變,效果還是非常誘人的。看一下效果圖
2018 新版 NavigationView實現了漢堡菜單和頂部菜單的近乎完美結合,可以參考官方商店的設計風格,就是用的這個控制項。
不過要用這個控制項,也不是那麼容易的,因為他需要Windows UI Library支持,而這個庫不支持VS2015,必須是2017或者更高版本。詳見 Getting started with the Windows UI Library
下麵就說一下實現的完整步驟吧。
1.安裝Microsoft.UI.Xaml
在NuGet中搜索Microsoft.UI.Xaml,需要勾選預發行版本。
然後需要將Microsoft.UI.Xaml添加到應用程式資源。
a. 如果你程式沒有其他的程式資源,那麼
<Application> <Application.Resources> <XamlControlsResources xmlns="using:Microsoft.UI.Xaml.Controls"/> </Application.Resources> </Application>
b. 如果已存在其他的,那麼只需要合併一下即可
<Application> <Application.Resources> <ResourceDictionary> <ResourceDictionary.MergedDictionaries> <XamlControlsResources xmlns="using:Microsoft.UI.Xaml.Controls"/> </ResourceDictionary.MergedDictionaries> </ResourceDictionary> </Application.Resources> </Application>
2. 添加引用
在xaml文件中,添加
xmlns:controls="using:Microsoft.UI.Xaml.Controls"
在.cs文件中添加
using MUXC = Microsoft.UI.Xaml.Controls;
3. 編寫Xaml界面
註意一下被註釋掉的代碼,你可以反註釋一下,看看效果。
我這裡主要是模仿一下商店的風格。
代碼和官方的不大一樣,主要是控制項NavigationView,官方並沒有在前面加上命名空間controls,我這裡加上了。如果不加的話,編譯器並不知道i用的是新版的控制項。後臺代碼如果不加的話,會爆出N個錯誤。
<Grid> <VisualStateManager.VisualStateGroups> <VisualStateGroup> <VisualState> <VisualState.StateTriggers> <AdaptiveTrigger MinWindowWidth="{x:Bind NavView.CompactModeThresholdWidth}" /> </VisualState.StateTriggers> <VisualState.Setters> <Setter Target="NavView.PaneDisplayMode" Value="Top"/> </VisualState.Setters> </VisualState> </VisualStateGroup> </VisualStateManager.VisualStateGroups> <controls:NavigationView x:Name="NavView" SelectionFollowsFocus="Enabled" ItemInvoked="NavView_ItemInvoked" IsSettingsVisible="True" Loaded="NavView_Loaded" BackRequested="NavView_BackRequested"> <controls:NavigationView.MenuItems> <controls:NavigationViewItem Content="Home" x:Name="home" Tag="home"> <controls:NavigationViewItem.Icon> <FontIcon Glyph=""/> </controls:NavigationViewItem.Icon> </controls:NavigationViewItem> <!--<controls:NavigationViewItemSeparator/>--> <!--<controls:NavigationViewItemHeader Content="Main pages"/>--> <controls:NavigationViewItem Icon="AllApps" Content="Apps" x:Name="apps" Tag="apps"/> <controls:NavigationViewItem Icon="People" Content="Games" x:Name="games" Tag="games"/> <controls:NavigationViewItem Icon="Video" Content="Movies and TVs" x:Name="moviestvs" Tag="moviestvs"/> <controls:NavigationViewItem Icon="Audio" Content="Music" x:Name="music" Tag="music"/> <controls:NavigationViewItem Icon="PhoneBook" Content="Books" x:Name="books" Tag="books"/> </controls:NavigationView.MenuItems> <!--<controls:NavigationView.AutoSuggestBox> <AutoSuggestBox x:Name="ASB" QueryIcon="Find"/> </controls:NavigationView.AutoSuggestBox>--> <!--<controls:NavigationView.HeaderTemplate> <DataTemplate> <Grid Margin="24,10,0,0"> <Grid.ColumnDefinitions> <ColumnDefinition Width="Auto"/> <ColumnDefinition/> </Grid.ColumnDefinitions> <TextBlock Style="{StaticResource TitleTextBlockStyle}" FontSize="28" VerticalAlignment="Center" Text="Welcome"/> <CommandBar Grid.Column="1" HorizontalAlignment="Right" VerticalAlignment="Top" DefaultLabelPosition="Right" Background="{ThemeResource SystemControlBackgroundAltHighBrush}"> <AppBarButton Label="Refresh" Icon="Refresh"/> <AppBarButton Label="Import" Icon="Import"/> </CommandBar> </Grid> </DataTemplate> </controls:NavigationView.HeaderTemplate>--> <Frame x:Name="ContentFrame"/> </controls:NavigationView> <TextBlock Text="New Navigation View" FontSize="12" Margin="12,6,0,0" HorizontalAlignment="Left" VerticalAlignment="Top"/> </Grid>
4. 添加後臺代碼
首先添加一下必要的引用
using System; using System.Collections.Generic; using System.Linq; using Windows.Foundation; using Windows.System; using Windows.UI.ViewManagement; using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; using Windows.UI.Xaml.Input; using Windows.UI.Xaml.Navigation; using MUXC = Microsoft.UI.Xaml.Controls;
紅色代碼部分是我自己添加的,官方沒有。
因為發現當初與設置界面的時候,拖動窗體改變大小,app會崩潰。目前已經提交官方pr,等待審核
private Type currentPage; // List of ValueTuple holding the Navigation Tag and the relative Navigation Page private readonly IList<(string Tag, Type Page)> _pages = new List<(string Tag, Type Page)> { ("home", typeof(HomePage)), ("apps", typeof(AppsPage)), ("games", typeof(GamesPage)), ("moviestvs", typeof(MovieandTVPage)), ("music", typeof(MusicPage)), ("books", typeof(BooksPage)), }; private void NavView_Loaded(object sender, RoutedEventArgs e) { // You can also add items in code behind //NavView.MenuItems.Add(new NavigationViewItemSeparator()); //NavView.MenuItems.Add(new NavigationViewItem //{ // Content = "Settings", // Icon = new SymbolIcon(Symbol.Folder), // Tag = "content" //}); //_pages.Add(("content", typeof(SettingsPage))); ContentFrame.Navigated += On_Navigated; // NavView doesn't load any page by default: you need to specify it NavView_Navigate("home"); // Add keyboard accelerators for backwards navigation var goBack = new KeyboardAccelerator { Key = VirtualKey.GoBack }; goBack.Invoked += BackInvoked; this.KeyboardAccelerators.Add(goBack); // ALT routes here var altLeft = new KeyboardAccelerator { Key = VirtualKey.Left, Modifiers = VirtualKeyModifiers.Menu }; altLeft.Invoked += BackInvoked; this.KeyboardAccelerators.Add(altLeft); } private void NavView_ItemInvoked(MUXC.NavigationView sender, MUXC.NavigationViewItemInvokedEventArgs args) { if (args.InvokedItem == null) return; if (args.IsSettingsInvoked) ContentFrame.Navigate(typeof(SettingsPage)); else { // Getting the Tag from Content (args.InvokedItem is the content of NavigationViewItem) var navItemTag = NavView.MenuItems .OfType<MUXC.NavigationViewItem>() .First(i => args.InvokedItem.Equals(i.Content)) .Tag.ToString(); NavView_Navigate(navItemTag); } } private void NavView_Navigate(string navItemTag) { var item = _pages.First(p => p.Tag.Equals(navItemTag)); if (currentPage == item.Page) return; ContentFrame.Navigate(item.Page); currentPage = item.Page; } private void NavView_BackRequested(MUXC.NavigationView sender, MUXC.NavigationViewBackRequestedEventArgs args) { On_BackRequested(); } private void BackInvoked(KeyboardAccelerator sender, KeyboardAcceleratorInvokedEventArgs args) { On_BackRequested(); args.Handled = true; } private bool On_BackRequested() { if (!ContentFrame.CanGoBack) return false; // Don't go back if the nav pane is overlayed if (NavView.IsPaneOpen && (NavView.DisplayMode == MUXC.NavigationViewDisplayMode.Compact || NavView.DisplayMode == MUXC.NavigationViewDisplayMode.Minimal)) return false; ContentFrame.GoBack(); return true; } private void On_Navigated(object sender, NavigationEventArgs e) { NavView.IsBackEnabled = ContentFrame.CanGoBack; if (ContentFrame.SourcePageType == typeof(SettingsPage)) { // SettingsItem is not part of NavView.MenuItems, and doesn't have a Tag NavView.SelectedItem = (MUXC.NavigationViewItem)NavView.SettingsItem; } else { var item = _pages.First(p => p.Page == e.SourcePageType); NavView.SelectedItem = NavView.MenuItems .OfType<MUXC.NavigationViewItem>() .First(n => n.Tag.Equals(item.Tag)); } }
如果你發現,代碼中
IList<(string Tag, Type Page)> _pages = new List<(string Tag, Type Page)>
報錯,請在NuGet中安裝 System.ValueTuple。
5. 延申擴展
商店還有一個效果,就是ScrollViewer向下拉的時候,再導航欄下麵會有一個模糊的玻璃效果。
這個效果官方也做了說明,參考
Scroll content under top pane
不過我的程式中沒做上去,因為 ScrollViewer的 CanContentRenderOutsideBounds 這個屬性,再17134中並沒有,應該在 Insider 17723出現了。
詳見
Windows 10 SDK Preview Build 17723 available now! JULY 31, 2018 10:36 AM
但是不曉得這個屬性,會不會照顧低版本系統呢。。。。。。又是一個坑!!!
我在HomePage裡面註釋了,預覽版可以嘗試一下。
<ScrollViewer> <!--<ScrollViewer CanContentRenderOutsideBounds"True">--> <StackPanel> <TextBlock FontSize="30" TextWrapping="Wrap" Margin="0,100,0,0" IsColorFontEnabled="True" HorizontalAlignment="Center" VerticalAlignment="Center"> <Run>For a seamless look+feel, if your app has pages that use a ScrollViewer and your navigation pane is top positioned, we recommend having the content scroll underneath the top nav pane. This can be achieved by setting the CanContentRenderOutsideBounds property on the relevant ScrollViewer to true.</Run> </TextBlock> <TextBlock Text="Home" FontSize="100" Margin="0,100,0,0" IsColorFontEnabled="True" HorizontalAlignment="Center" VerticalAlignment="Center"/> <TextBlock Text="Home" FontSize="100" Margin="0,100,0,0" IsColorFontEnabled="True" HorizontalAlignment="Center" VerticalAlignment="Center"/> <TextBlock Text="Home" FontSize="100" Margin="0,100,0,0" IsColorFontEnabled="True" HorizontalAlignment="Center" VerticalAlignment="Center"/> <TextBlock Text="Home" FontSize="100" Margin="0,100,0,0" IsColorFontEnabled="True" HorizontalAlignment="Center" VerticalAlignment="Center"/> <TextBlock Text="Home" FontSize="100" Margin="0,100,0,0" IsColorFontEnabled="True" HorizontalAlignment="Center" VerticalAlignment="Center"/> <TextBlock Text="Home" FontSize="100" Margin="0,100,0,0" IsColorFontEnabled="True" HorizontalAlignment="Center" VerticalAlignment="Center"/> </StackPanel> </ScrollViewer>
6. 再延申擴展一下
官方還說 Microsoft.UI.Xaml 支持更低的系統版本,最低支持到14393。但是在編譯程式的時候,目標系統一定要是17134或者更高。
有低版本的系統,你可以在低版本上跑一下看看。反正半個月前是不能運行的,我測試過。
不過你的實際程式可能還有其他的官方庫,那些有的可能最低是16299,所以14393也只是一個水中月而已。
7. GayHub項目地址
https://github.com/hupo376787/NewNavigationView
參考官方文檔: