SettingsFlyout Class For C#/XAML Windows 8 Apps

One of the interesting things about Windows 8 Modern UI app development is the amount of boilerplate code that the project wizard adds to your project. Why some of the classes are not part of the WinRT base class library is not clear and not hugely important. It is more puzzling to think of the things that are not provided such as a settings flyout wrapper. If you're new to all this, the settings flyout1 is that thing that appears to the right when you use the Settings charm2. Windows has its own implementation for the system level Settings but your app must implement this for its own settings.

I discovered the hard way that to get certified in the Windows Store you must support the settings contract so you can provide "about" information. Adding this isn't particularly difficult, but there is a lot of boilerplate that can be abstracted away. Not only that, but if you're using the WebView, you need to know when the settings come and go to ensure the WebView is properly hidden as it would otherwise draw all over your beautiful settings (I'll perhaps talk about XAML apps and the WebView another time, when I've calmed down a bit).

To simplify this I wrote SettingsFlyout, a simple wrapper that handles the boilerplate activity of showing a UserControl as your settings while providing some handy events to track any settings flyout being shown or hidden. You may notice that other than the dimensions of this flyout, it could easily be adapted to support any of your flyout needs. However, I'm not sure that there are many valid reasons for flyout usage in Modern UI apps other than the standard system implementations and settings. Therefore, I'll leave that up to you, I'd hate to lead you into bad habits.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;

namespace SomewhatAbstract
{
    /// <summary>
    /// Provides a wrapper for showing settings with events to track any settings flyout coming or going.
    /// </summary>
    public class SettingsFlyout
    {
        private const int FlyoutWidth = 346;
        private Popup popup;

        /// <summary>
        /// Shows the given control in the flyout.
        /// </summary>
        public void ShowFlyout(UserControl control)
        {
            this.popup = new Popup();
            this.popup.Opened += OnPopupOpened;
            this.popup.Closed += OnPopupClosed;
            Window.Current.Activated += OnWindowActivated;
            this.popup.IsLightDismissEnabled = true;
            this.popup.Width = FlyoutWidth;
            this.popup.Height = Window.Current.Bounds.Height;

            control.Width = FlyoutWidth;
            control.Height = Window.Current.Bounds.Height;

            this.popup.Child = control;
            this.popup.SetValue(Canvas.LeftProperty, Window.Current.Bounds.Width - FlyoutWidth);
            this.popup.SetValue(Canvas.TopProperty, 0);
            this.popup.IsOpen = true;
        }


        private void OnWindowActivated(object sender, Windows.UI.Core.WindowActivatedEventArgs e)
        {
            if (e.WindowActivationState == Windows.UI.Core.CoreWindowActivationState.Deactivated)
            {
                this.popup.IsOpen = false;
            }
        }

        private void OnPopupClosed(object sender, object e)
        {
            Window.Current.Activated -= OnWindowActivated;
            OnSettingsClosed(EventArgs.Empty);
        }

        private void OnPopupOpened(object sender, object e)
        {
            OnSettingsOpened(EventArgs.Empty);
        }

        /// <summary>
        /// Raised to indicate settings flyout has been opened.
        /// </summary>
        public static event EventHandler SettingsOpened;
        private static void OnSettingsOpened(EventArgs args)
        {
            var handler = SettingsFlyout.SettingsOpened;
            if (handler != null)
            {
                handler(null, args);
            }
        }

        /// <summary>
        /// Raised to indicate settings flyout has been closed.
        /// </summary>
        public static event EventHandler SettingsClosed;
        private static void OnSettingsClosed(EventArgs args)
        {
            var handler = SettingsFlyout.SettingsClosed;
            if (handler != null)
            {
                handler(null, args);
            }
        }
    }
}

Using the SettingsFlyout class is as simple as this:

// Add an About command
var about = new SettingsCommand("about", "About", (handler) =>
{
    var settings = new SettingsFlyout();
    settings.ShowFlyout(new MyAboutSettingsControl());
});

If you find this useful or you did something similar yourself, I would love to hear about it. Is there something you feel is missing that should be there either in WinRT or the project template? Have you created any useful utility classes like this that could be used in almost every app?

  1. A flyout is the new Windows 8 modern UI term for what we might've called a popup, dialog or tooltip in the past. It's anything that appears over your application and you use a Popup control to show them as you would in Silverlight or WPF. []
  2. The Settings charm is the cog-like button that appears when you swipe from the right or hover your mouse in the lower right (or press Windows+C). It looks a lot like an icon, except it's not. It's a charm. []