Hamburger menu on Windows 10 Universal App
The new Windows 10 is here and clients demand new updated content available across a wide variety of devices.
The new Visual Studio 2015 and Windows 10 SDK are providing the needed tools to start creating innovative new applications for Windows 10 users.
This post is about one of the new fetaured in Universal Windows Platform (UWP) – the SplitView class.
This new features allows you to create animated side menu that is also called “drawer menu”, “navigation drawer”, “hamburger menu” or even “sandwich menu”.
The code to use this class is simple.
<SplitView> <SplitView.Content> singleObject </SplitView.Content> <SplitView.Pane> singleObject </SplitView.Pane> </SplitView>
Using it in this simple way will limit you to single page application and will force the content XAML to be large and complicated.
I will try now to explain how to convert your application main page into navigation page and navigate to multiple pages by loading them into the SplitView content frame.
SplitView initial params
<SplitView x:Name="MySplitView" DisplayMode="CompactOverlay" IsPaneOpen="False" CompactPaneLength="50" OpenPaneLength="150">
The DisplayMode property can be set to a various of values giving you the ability to choose whether you want to cover the content or push it to side when menu is open.
Navigation buttons
<SplitView.Pane> <StackPanel Background="Gray"> <Button x:Name="HamburgerButton" FontFamily="Segoe MDL2 Assets" Content="" Width="50" Height="50" Background="Transparent" Click="HamburgerButton_Click"/> <StackPanel Orientation="Horizontal" Tapped="HomeTextBlock_Tapped"> <Button x:Name="MenuButton1" FontFamily="Segoe MDL2 Assets" Content="" Width="50" Height="50" Background="Transparent" Click="MenuButtonHome_Click"/> <TextBlock Text="Home" FontSize="18" VerticalAlignment="Center" Tapped="HomeTextBlock_Tapped" /> </StackPanel> <StackPanel Orientation="Horizontal" Tapped="PageTextBlock_Tapped"> <Button x:Name="MenuButton2" FontFamily="Segoe MDL2 Assets" Content="" Width="50" Height="50" Background="Transparent" Click="MenuButtonPage_Click"/> <TextBlock Text="Page" FontSize="18" VerticalAlignment="Center" Tapped="PageTextBlock_Tapped" /> </StackPanel> </StackPanel> </SplitView.Pane>
The code behind this includes only two things – shifting the menu and navigating to a new page.
private void HamburgerButton_Click(object sender, RoutedEventArgs e) { MySplitView.IsPaneOpen = !MySplitView.IsPaneOpen; }
Main Page Initialization
This is a two step change.
First I need to add constructor to MainPage where I can deliver the application current content frame in order to assign this frame to SplitView content.
public MainPage(Frame frame) { this.InitializeComponent(); MySplitView.Content = frame; //... }
In App.xaml I need to force MainPage creation applying this parameter.
protected override void OnLaunched(LaunchActivatedEventArgs e) { //.. Frame rootFrame = Window.Current.Content as Frame; if (rootFrame == null) { rootFrame = new Frame(); //.. Window.Current.Content = new MainPage(rootFrame); } if (rootFrame.Content == null) { rootFrame.Navigate(typeof(MainPage), e.Arguments); } Window.Current.Activate(); }
I didn’t copy the whole content of OnLaunched event as I needed to show only one change:
Window.Current.Content = new MainPage(rootFrame);
Content pages
From this example I will create two pages without any complication in design, because I only want to show you the navigation.
Page XAML will be cleared down to this:
<Grid Background="Black"> <TextBlock Text="SplitView - Home" FontSize="54" Foreground="White" HorizontalAlignment="Center" VerticalAlignment="Center"/> </Grid>
Same structure and different name for the second page.
Content Initialization
After loading the content frame we need to fill it with content from the home page.
public MainPage(Frame frame) { this.InitializeComponent(); MySplitView.Content = frame; (MySplitView.Content as Frame).Navigate(typeof(BlankPage1)); }
This is all we need to load and initializate the page with first conent.
Navigation
The key here is that we have to navigate the frame not the applicaiton:
private void MenuButtonHome_Click(object sender, RoutedEventArgs e) { (MySplitView.Content as Frame).Navigate(typeof(BlankPage1)); } private void MenuButtonPage_Click(object sender, RoutedEventArgs e) { (MySplitView.Content as Frame).Navigate(typeof(BlankPage2)); }
From this point further Frame level of navigation is required to keep the side menu in place.
One issue may appear – the use of back button, but it have to be handled manually.