Cimbalino Toolkit Hamburger controls for UWP

Like it or not, the so called “Hamburger” design pattern has made its way to pretty much every platform, including the Windows Universal Apps!

Most Windows 10 native apps already show this new pattern, even a classic like the Calculator app!

However, for reasons unknown, Microsoft didn’t provide any Hamburger related control on the SDK base controls… frankly, this move brings back to memory when Windows Phone 7 SDK was launched without the Panorama and Pivot controls, the foundation of the whole “Metro” design guidelines!

The only alternative I’ve found is to use the Template 10, a “set of Visual Studio project templates”!

However, I’ve found that Template 10 version for Hamburger adds a bit of too much “fat” for my own taste, hence why I’ve been working on an alternative for the past last few weeks!

Introducing the Cimbalino Toolkit Controls

Starting with version 2.2.0 (currently still in beta 1), the Cimbalino Toolkit will feature a new package called Cimbalino.Toolkit.Control, and as the name suggests, it’s a control library for app developers.

Currently, the package features 3 controls:

  • HamburgerFrame
  • HamburgerTitleBar
  • HamburgerMenuButton

HamburgerFrame

Starting from the top, the HamburgerFrame control is a full replacement for the native Frame root control used in the app.xaml.cs file.

The control provides 3 content containers represented by the Header, SubHeader, and Pane properties, and on the center, it will show the navigated content:

HamburgerFrame container thumb

Obviously, you can specify content for this containers however you would like, or just leave them blank!

The Header allows content to be presented above the Pane, so it will never be hidden by it:

HamburgerFrame container thumb

The SubHeader allows content to be presented on the right side of the Pane. This means that if the pane is in one of the “overflow” modes it will show on top of this container, hiding the content behind it:

HamburgerFrame container thumb

The control also provides background properties for all these containers (HeaderBackground, SubHeaderBackground, and PaneBackground).

To make the life easier of developers, I’ve “borrowed” the VisualStateNarrowMinWidth, VisualStateNormalMinWidth, and VisualStateWideMinWidth properties from Template 10, which allow to specify the break points where the pane state and location will readjust. If you don’t want to use these, you can always do it manually with the exposed pane related properties (IsPaneOpen, DisplayMode, OpenPaneLength, CompactPaneLength, …).

HamburgerTitleBar

The HamburgerTitleBar control provides a basic Hamburger button on the left side (can be hidden with the MenuButtonVisibility property), and a Title property.

HamburgerTitleBar

This is a quite rudimentar and easy to use control, yet developers might want to just go ahead and create their own version of this control and place it on their apps!

HamburgerMenuButton

Finally, the HamburgerMenuButton is the button you’ll be using in the pane to indicate the available menu options!

This control shows a left-side icon and an optional label (through the Icon and Content properties):

HamburgerMenuButton basic states

The regular approach here will be to just place all the HamburgerMenuButton controls inside a vertical StackPanel, but one can also stack them horizontally, and in this case, we would only show the icon and hide the label (using the provided LabelVisibility property).

The NavigationSourcePageType property allow developers to specify the destination page type for navigation purposes. If the property is set, the button will automatically highlight anytime the page is the frame current navigation content.

So how can I use these in my app?

First step is to add the Cimbalino.Toolkit.Controls NuGet package to the project!

Then, create a new user control to define your menu; in it, add as many HamburgerMenuButton instances as the number of options you want to present!

Here’s how your menu might look like:

<UserControl x:Class="App1.View.HamburgerPaneControl"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:controls="using:Cimbalino.Toolkit.Controls"
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             xmlns:view="using:App1.View"
             d:DesignHeight="300"
             d:DesignWidth="400"
             mc:Ignorable="d">

    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>

        <StackPanel>
            <controls:HamburgerMenuButton Content="Home" NavigationSourcePageType="view:MainPage">
                <controls:HamburgerMenuButton.Icon>
                    <FontIcon FontSize="16" Glyph="& #xE80F;" />
                </controls:HamburgerMenuButton.Icon>
            </controls:HamburgerMenuButton>

            <controls:HamburgerMenuButton Content="Details" NavigationSourcePageType="view:DetailsPage">
                <controls:HamburgerMenuButton.Icon>
                    <FontIcon FontSize="16" Glyph="& #xE8BC;" />
                </controls:HamburgerMenuButton.Icon>
            </controls:HamburgerMenuButton>
        </StackPanel>

        <controls:HamburgerMenuButton Grid.Row="1"
                                  Content="Settings"
                                  NavigationSourcePageType="view:SettingsPage">
            <controls:HamburgerMenuButton.Icon>
                <FontIcon FontSize="16" Glyph="& #xE713;" />
            </controls:HamburgerMenuButton.Icon>
        </controls:HamburgerMenuButton>
    </Grid>
</UserControl>

Next, open the app.xaml.cs file and replace this line:

rootFrame = new Frame();

with this:

rootFrame = new Cimbalino.Toolkit.Controls.HamburgerFrame()
{
    Header = new Cimbalino.Toolkit.Controls.HamburgerTitleBar()
    {
        Title = "App1"
    },
    Pane = new View.HamburgerPaneControl()
}

Congratulation: your app now has a universal Hamburger menu with a nice title bar! πŸ™‚

App with HamburgerFrame

Next steps might be to create a separate user control to hold the HamburgerTitleBar, which will then allow you to bind the Title property to view model (making it easier to update on a page by page basis).

To make things easier, I’ve provided the source code for a simple app using these controls!

  • Pingback: Dew Drop – March 22, 2016 (#2213) | Morning Dew()

  • Pingback: Cimbalino Toolkit 2.2.0 – pedrolamas.com()

  • corcus

    Hi, and thanks for a great control implementation. I too, find the Template 10 control cannot be used without using the rest of Template 10. I am implementing a control to replace the HamburgerTitleBar. Besides the title, it will contain a few buttons. I would like these buttons to invoke commands in the ViewModel associated with the page displayed at the time. How do you propose I go about this?
    I have two ideas.
    1) Not use a Header for the HamburgerFrame at all and instead use my control in every page.
    2) Use my control as a Header and somehow get access to the DataContext of the page displayed, to find and execute the command.

    I’d like to go with 2 but I don’t know how to do it. Do you have any suggestions?

    • Hey corcus, glad you like the control! πŸ™‚ I’d definitely go with “door nΒΊ2” and there are quite a few options to achieve it:
      1) Create a HamburgerViewModel and use it as VM for your header control, then just inject it in your page VM’s and manipulate as required
      2) Similar to 1 above, but instead create a HamburgerService, which will just manipulate the header control directly (without binding)
      3) Use attached properties! Take a look at the Hamburger.cs https://github.com/Cimbalino/Cimbalino-Toolkit/blob/master/src/Cimbalino.Toolkit.Controls%20(UWP)/Helpers/Hamburger.cs file which allows you to set a header per page! You can use a similar approach for what you need, all straight from the page XAML!

      I’m planning to write a blog post about how to use attached properties to manipulate the HamburgerFrame and its controls, but I haven’t started writing it as of yet…

      • corcus

        Hi again. After your suggestion I went on and created a title bar with a back button (like the News,Sports etc apps in windows 10) and a content presenter to allow for addition of other content. I also added the supporting attached properties to control the title and the back button visibility.

        It’s not complete yet but I am wondering if you are accepting pull requests and if you are interested in such a control.

  • sistemas

    How would you use this in VB. Stuck on replacing “rootFrame”. πŸ™

    • You’d use it the same way that in C#… I’m not actually following whats the problem with VB! :

      • sistemas

        I’ve never done any C# and got “some” VB experience. VB is definitely the one I’m more comfortable with, but I have NO idea how to do:

        rootFrame = new Cimbalino.Toolkit.Controls.HamburgerFrame()
        {
        Header = new Cimbalino.Toolkit.Controls.HamburgerTitleBar()
        {
        Title = “App1”
        },
        Pane = new View.HamburgerPaneControl()
        }

        in VB. πŸ˜›

  • John

    Fuck you. It doesn’t work. You need initialize component. Give an example. Where we should locate our pages? Where!? Very bad tutorial.

  • John

    How to change title?

    • I’d first request that you moderate your words when commenting on this blog!

      On your previous comment you asked about a sample, there’s now a link to a sample app source code which uses these controls.

      One way to change the Title would be to store the HamburgerTitleBar instance on App.xaml.cs instead of declaring it as I did above, and then use something like ((App)Application.Current).TheHamburgerTitleBarInstance.Title to access it.

      • John

        Sorry for my previous comment, it was a joke. And I deleted it after wrote. Excuse me, again. All ok?

        • Indeed you did! Fair enough, no harm done and all is good! πŸ™‚

    • John

      For a soulution, I found this one:
      HamburgerFrame rootFrame = Window.Current.Content as HamburgerFrame;
      if (rootFrame == null)
      return;
      HamburgerTitleBar htbMain = rootFrame.Header as HamburgerTitleBar;
      if (htbMain == null)
      return;
      htbMain.Title = “My title”;

  • Ivan

    Hi. How to change color of hamburger icon in title bar?