Snapping in Windows 8 Apps

One of the decisions that Microsoft made with Windows 8 is to support the concept of “snapping”.  This allows the user to have two applications running on the screen at one time and is one of the features with distinguishes Windows 8 from its competitors.  This gives a unique experience for the user and adds to productivity.  However, it does add another dimension for the develop to consider when creating applications.  But Microsoft makes it pretty easy to handle.

Windows Resizing

Changes in window size are nothing new in applications for any platform and the trend has been rather constant to expand the size (or density) of mobile form factor screens in recent years.  Just as we had to deal with screen size change when the tablet was introduced, and subsequently had to adjust when Apple unveiled the Retina display, now we adjust to understand apps can run in different sizes.
In Windows 8 the display modes are Snapped, Fill, Full.  Snapped is when the application window is “snapped” to the right or left in something of a sidebar look. The Fill state occurs when one application is snapped, the other is said to “fill” the remaining portion of the screen.  Finally, Full, is when the application has the window to itself and is the default running mode for RT applications.

Handling the Size Change

Handling this change is pretty easy.  The approach I took was to define a base class called LayoutAwarePage.  Note that, VS2012 templates do provide this same class with a similar implmentation.  In fact, it was in studying these default templates that I was able to learn the most about “snapping”.  Whenever the Windows Size changes, the SizeChanged event fires.  Within this event handler access the ApplicationView.Value value, this will contain a string representation of the mode (Snapped, Full, Filled).  This will give you a clear indication as to which display mode you are in.  Here is my abstract base class, LayoutAwarePage:

public class LayoutAwarePage : Page
    {
        protected LayoutAwarePage()
        {
            if (Windows.ApplicationModel.DesignMode.DesignModeEnabled) return;
            SizeChanged += OnSizeChanged;
        }

        private void OnSizeChanged(object sender, SizeChangedEventArgs args)
        {
            // get the view type
            var displayType = ApplicationView.Value.ToString().AsDisplayType();

            // call our handler
            HandleLayoutChange(displayType);
        }

        protected virtual void HandleLayoutChange(DisplayModeType displayType)
        {
            return;
        }
    }

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

The HandleLayoutChange method is virtual so that each page can override it, thus allowing that page to customize how it handles the changing layout.  Based on examination of the default templates, I would say Microsoft is recommended developers use Visual States to handle this. I havent been able to get mine to work just yet, so I have dropped back to talking to the control directly, bit of a deviation from MVVM that I love, example:

public sealed partial class MainView : LayoutAwarePage
    {
        public MainView()
        {
            this.InitializeComponent();
        }

        protected override void HandleLayoutChange(DisplayModeType displayType)
        {
            FilledGridView.Visibility = Visibility.Visible;
            SnappedListView.Visibility = Visibility.Collapsed;
            PageTitle.Style = (Style) App.Current.Resources["PageTitle"];
            PageTitle.Margin = new Thickness(20,0,0,7);
            AppBar.Visibility = Visibility.Visible;

            if (displayType == DisplayModeType.Snapped)
            {
                FilledGridView.Visibility = Visibility.Collapsed;
                SnappedListView.Visibility = Visibility.Visible;
                PageTitle.Style = (Style) App.Current.Resources["SnappedPageTitle"];
                PageTitle.Margin = new Thickness(10, 0, 0, 7);
                AppBar.Visibility = Visibility.Collapsed;
            }
        }
    }

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

Remember, I am not advocating doing it this way, Visual State Groups remove a lot of this code in favor of something simpler.  The point here is to see how the developer is responsible for handling this.

Tips for Creating Snappable Pages

So one of the things that I learned in going through the Codemash Windows 8 app was generally you want to start with the “snapped” view. I feel the reason for this is the snapped view isnt going to be fancy or take advantage of the screen size.  The purpose of the “snapped” view is to provide the absolute minimum what the user would need, kind of data intensive view.  So if you are using a GridView to display nice tiles and support the horizontal swipe, maybe in snap you use the ListView for a vertical swipe scroll.  That is a pretty common use case.
Keep in mind that some pages will not be snappable, or shouldnt be rather.  An example of this in the Codemash app is the Session Detail.  There is just too much information on this screen to where it would be usable in the snapped state. To counter this, I looked at several apps from Microsoft (the Store app in particular) to see what they did.  They generally simple display the application icon on a solid color. This way the user knows the app is open, but that they have to expand the window to use it.
Finally, for the pages which are snappable, make sure you support back navigation and disable any app bars, if it makes sense.  For example, you have three buttons in the app bar, it might make sense to display them horizontally in the snapped state, or you could make them go vertical when snapped.  The choice is yours.  There is a lot of freedom with what you can do when display type changes.

Conclusion

Supporting snapped pages in Windows 8 apps is not required but any well polished app is going to need to support these different view states.  Microsoft makes this easy and straightforward, and with a little bit of abstraction can be made easy and consistent within your applications.  Furthermore, the snapped state requires you, the developer, to give even deeper thought as to how the user will interact with your application. I view this as a great challenge and a chance to really expand the experience for the user.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s