Blog

Taming the SplitView Control in Windows 10

Of all the new controls featured in Windows 10, SplitView is perhaps the most emblematic. SplitView makes it easy to implement “hamburger menu” interfaces like the ones featured in Windows 10’s built-in News, Sports, and Photos apps, among others. A hamburger icon consisting of three horizontal bars sits atop a ribbon on the left side of the window. The ribbon contains iconic buttons, most of which navigate to another page in the app when clicked. Typically, but not always, clicking the hamburger icon expands the ribbon to reveal labels to the right of the icons. It’s an easy navigation pattern to learn, and even if somewhat controversial, it’s already familiar to users who have seen similar UI paradigms used in Web sites and mobile apps.

Most developers who set out to use SplitView for the first time are surprised at how lean it is. SplitView has little in the way of a default UI other than a pane that expands and collapses. There is no SplitViewItem class for placing buttons in a SplitView, and precious little guidance on how to implement them. Plus, incorporating a SplitView in your app requires some restructuring of the code that Visual Studio dumps into App.xaml.cs. I had hoped that the RTM version of Visual Studio 2015 might offer a SplitView project template, but alas, it does not. So it’s up to the developer to fill the void.

Microsoft’s Jerry Nixon recently published a great article on using SplitView to build hamburger menus similar to the ones featured in Windows 10’s built-in apps. Among other things, he described how to implement SplitView buttons by retemplating radio-button controls, and how to use glyphs in the Segoe MDL2 Assets character set as button icons. I built on that to produce a sample to help you write SplitView apps of your own. You can start with my code and XAML and modify it as needed to take the pain out of SplitView controls. If that sounds enticing, then let’s get started.

Introducing SplitViewDemo

You can download my SplitViewDemo solution and open it in Visual Studio 2015. (You’ll need to have the Windows 10 tools for Visual Studio 2015 installed.) Here’s how SplitViewDemo looks when it starts up:

Clicking the hamburger icon in the upper-left corner expands the SplitView pane to reveal labels next to the icons:

The app contains four navigable pages: a home page, a search page, a settings page, and an about page. Clicking a button in the SplitView pane navigates to the corresponding page:

The SplitView control is declared in MainPage.xaml, which isn’t a navigable page, but serves as a container of sorts for the other pages. Here’s how the SplitView is declared in MainPage.xaml:

<SplitView x:Name="ShellSplitView" DisplayMode="CompactOverlay"
    IsPaneOpen="False" CompactPaneLength="48" OpenPaneLength="200"
    PaneBackground="{ThemeResource SplitViewBackgroundBrush}">
    <SplitView.Pane>
        <StackPanel>
            <!-- Menu (hamburger) button -->
            <RadioButton Style="{StaticResource SplitViewMenuButtonStyle}"
                Click="OnMenuButtonClicked" />

            <!-- Home button -->
            <RadioButton Tag="" Content="Home"
                Style="{StaticResource SplitViewNavButtonStyle}"
                Checked="OnHomeButtonChecked" IsChecked="True" />

            <!-- Search button -->
            <RadioButton Tag="" Content="Search"
                Style="{StaticResource SplitViewNavButtonStyle}"
                Checked="OnSearchButtonChecked" />

            <!-- Settings button -->
            <RadioButton Tag="" Content="Settings"
                Style="{StaticResource SplitViewNavButtonStyle}"
                Checked="OnSettingsButtonChecked" />

            <!-- About button -->
            <RadioButton Tag="" Content="About"
                Style="{StaticResource SplitViewNavButtonStyle}"
                Checked="OnAboutButtonChecked" />
        </StackPanel>
    </SplitView.Pane>
</SplitView>

Setting the SplitView’s DisplayMode property to “CompactOverlay” configures the SplitView so that the open pane overlays the content to its right (as opposed to pushing that content further to the right). IsPaneOpen=”False” means the SplitView pane is initially collapsed, while CompactPaneLength=”48” and OpenPaneLength=”200” specify the width of the pane when it is collapsed and expanded. The RadioButtons declared in the <SplitView.Pane> element are the buttons displayed in the SplitView. They don’t look like radio buttons because they’ve been retemplated in SplitViewStyles.xaml. But they act like radio buttons in that checking one button in a group unchecks the others. They also fire Click events when clicked and Checked events when toggled on or off.

If you examine the RadioButton templates in SplitViewStyles.xaml (there are two of them: one for the hamburger button, and another for the navigation buttons), you’ll discover that you specify the button’s icon by assigning text to the Tag property, and you specify the button’s label by assigning text to the Content property. The templates also specify that the characters used in the Tag property come from the Segoe MDL2 Assets character set, which you can view in Windows’ Character Map application:

The Checked handlers in MainPage.xaml.cs close the SplitView pane and navigate the user to another page when a navigation button is clicked. The hamburger button is handled slightly differently. Rather than navigate to another page, its Click handler toggles the SplitView pane open or closed and unchecks the button since we don’t want it to act like a radio button:

private void OnMenuButtonClicked(object sender, RoutedEventArgs e)
{
    ShellSplitView.IsPaneOpen = !ShellSplitView.IsPaneOpen;
    ((RadioButton)sender).IsChecked = false;
}

private void OnHomeButtonChecked(object sender, RoutedEventArgs e)
{
    ShellSplitView.IsPaneOpen = false;
    if (ShellSplitView.Content != null)
        ((Frame)ShellSplitView.Content).Navigate(typeof(HomePage));
}

private void OnSearchButtonChecked(object sender, RoutedEventArgs e)
{
    ShellSplitView.IsPaneOpen = false;
    if (ShellSplitView.Content != null)
        ((Frame)ShellSplitView.Content).Navigate(typeof(SearchPage));
}

private void OnSettingsButtonChecked(object sender, RoutedEventArgs e)
{
    ShellSplitView.IsPaneOpen = false;
    if (ShellSplitView.Content != null)
        ((Frame)ShellSplitView.Content).Navigate(typeof(SettingsPage));
}

private void OnAboutButtonChecked(object sender, RoutedEventArgs e)
{
    ShellSplitView.IsPaneOpen = false;
    if (ShellSplitView.Content != null)
        ((Frame)ShellSplitView.Content).Navigate(typeof(AboutPage));
}

Radio buttons that you style with SplitViewNavButtonStyle act as a group – that is, checking one unchecks the others – because the template included in that style assigns all the buttons the same GroupName property (“Primary”). If you want to divide buttons in a SplitView into two or more groups, simply override the default GroupName property in your RadioButton declarations. Similarly, you can change the colors used in the SplitView by modifying the SolidColorBrush resources declared near the top of SplitViewStyles.xaml.

Framing the SplitView

Including a SplitView control in your app is a little more involved than simply declaring one in a page. You need to assign a Frame control to the SplitView’s Content property. Normally, the Frame is created by code generated by Visual Studio in App.xaml.cs and assigned to the window’s Content property. To support a SplitView, you must modify that code to assign the page that hosts the SplitView to Window.Content and assign the Frame to SplitView.Content. Here’s the relevant code in App.xaml.cs:

_rootFrame = new Frame();
 .
 .
 .
Window.Current.Content = new MainPage(_rootFrame);

_rootFrame is a private field I added to App.xaml.cs to hold a reference to the Frame. It’s needed later on if the user clicks the Back button. Since the app knows nothing about the SplitView in MainPage.xaml, I modified the MainPage constructor to assign the Frame to SplitView.Content:

public MainPage(Frame frame)
{
    this.InitializeComponent();
    this.ShellSplitView.Content = frame;
}

If you use the Back-button code I presented in an earlier blog post, you’ll also need to modify it to work with the Frame. See App.xaml.cs to see how I handled that in SplitViewDemo.

Wrapping Up

Feel free to use my sample code as the starting point for SplitView apps of your own. And stay tuned for additional articles on some of the cool new features of Windows 10 that developers can leverage to build great universal Windows apps.

Jeff Prosise

View Comments

  • back button doesn't change the splitview selected radio option to match the frame navigated to. How do I fix this?

  • back button doesn't change the splitview selected radio option to match the frame navigated to. How do I fix this?

  • For anyone having problems using his back button tutorial with this (i.e. Navigating back doesn't change the selected item state to match) I have a quick solution. Make sure you name all your menu buttons after the page they lead to (i.e. HomePageButton) and put this code in the constructor right after "this.ShellSplitView.Content = frame;"
    //code to update menu selected on backpress
    var update = new Action(() =>
    {
    // as long as your buttons are named the same as the page name with "Button" (i.e. HomePageButton) at the end this will work
    var umb = (RadioButton)this.FindName(((Frame)ShellSplitView.Content).SourcePageType.Name.ToString() +"Button");
    umb.IsChecked = true;
    });
    frame.Navigated += (s, e) => update();
    this.Loaded += (s, e) => update();
    this.DataContext = this;
    Not the most elegant solution, but it works until this guy provides code to show a better way of doing it.

  • For anyone having problems using his back button tutorial with this (i.e. Navigating back doesn't change the selected item state to match) I have a quick solution. Make sure you name all your menu buttons after the page they lead to (i.e. HomePageButton) and put this code in the constructor right after "this.ShellSplitView.Content = frame;"
    //code to update menu selected on backpress
    var update = new Action(() =>
    {
    // as long as your buttons are named the same as the page name with "Button" (i.e. HomePageButton) at the end this will work
    var umb = (RadioButton)this.FindName(((Frame)ShellSplitView.Content).SourcePageType.Name.ToString() +"Button");
    umb.IsChecked = true;
    });
    frame.Navigated += (s, e) => update();
    this.Loaded += (s, e) => update();
    this.DataContext = this;
    Not the most elegant solution, but it works until this guy provides code to show a better way of doing it.

Recent Posts

8-Step AWS to Microsoft Azure Migration Strategy

Microsoft Azure and Amazon Web Services (AWS) are two of the most popular cloud platforms.…

5 days ago

How to Navigate Azure Governance

 Cloud management is difficult to do manually, especially if you work with multiple cloud…

2 weeks ago

Why Azure’s Scalability is Your Key to Business Growth & Efficiency

Azure’s scalable infrastructure is often cited as one of the primary reasons why it's the…

4 weeks ago

Unlocking the Power of AI in your Software Development Life Cycle (SDLC)

https://www.youtube.com/watch?v=wDzCN0d8SeA Watch our "Unlocking the Power of AI in your Software Development Life Cycle (SDLC)"…

1 month ago

The Role of FinOps in Accelerating Business Innovation

FinOps is a strategic approach to managing cloud costs. It combines financial management best practices…

1 month ago

Azure Kubernetes Security Best Practices

Using Kubernetes with Azure combines the power of Kubernetes container orchestration and the cloud capabilities…

2 months ago