When you develop a Windows Store application, a big deal is to find a place for every feature, connecting together the available space with a reliable user experience. Together with the canvas of the application, Windows Store apps give you some other "surfaces" where you can collocate your commands and features, most of the times following the strict rules that have been collected under the UX Guidelines. These so called "surfaces" have the intent of create additional room with the purpose of leaving the interface more clean and simple, without omitting important features that are discoverable using common gestures. Swipe to side of the screen, tap & hold and other gestures bring the user to open expected that appear on demand to accomplish additional tasks.
The AppBar "surface"
When an application is opened, most of the times it shows only the main canvas area. This surface contains the main content, often displayed using a GridView that creates the illusion of a potentially infinite space horizontally, but if the application follows the ux guidelines it does not show any evident command. Usually the first place where you have to search is the Application bar. The application bar appears when you swipe the top or bottom side and cant contain a number of items, expecially commands in the lower one and navigation items in the top one.
Defining an Application bar is slightly different in XAML and HTML. Since in XAML there are some properties that you may assign using markup, in HTML you have a WinJS control in which you define the layout of the items. Let see an example for each language:
1: <Page.BottomAppBar>
2: <AppBar>
3: <Grid>
4: <StackPanel Orientation="Horizontal">
5: <Button Style="{StaticResource RefreshAppBarButtonStyle}" />
6: <Button Style="{StaticResource FavoriteAppBarButtonStyle}" />
7: </StackPanel>
8: <StackPanel Orientation="Horizontal" HorizontalAlignment="Right" >
9: <Button Style="{StaticResource RefreshAppBarButtonStyle}" />
10: <Button Style="{StaticResource SettingsAppBarButtonStyle}" />
11: </StackPanel>
12: </Grid>
13: </AppBar>
14: </Page.BottomAppBar>
This snippets defines a bottom application bar (look at the BottomAppBar property). Inside the application bar it is contained a Grid with two horizontal StackPanels. The purpose of the stack panels is to create two areas to host a number of buttons left and right aligned. As you can see the buttons are defined simply using a Style that is peeked up by the StandardStyles.xaml file. (Please take note that in Windows 8.1 this file has been embedded directly into the framework) These styles are a collection of buttons that include icons and titles in a standardized way. Let see the same example in HTML:
1: <div id="bottomAppBar" data-win-control="WinJS.UI.AppBar">
2: <button
3: data-win-control="WinJS.UI.AppBarCommand"
4: data-win-options="{label:'Refresh', icon:'refresh', section:'selection'}">
5: </button>
6: <button
7: data-win-control="WinJS.UI.AppBarCommand"
8: data-win-options="{label:'Favorite', icon:'favorite', section:'selection'}">
9: </button>
10: <button
11: data-win-control="WinJS.UI.AppBarCommand"
12: data-win-options="{label:'Refresh', icon:'refresh', section:'global'}">
13: </button>
14: <button
15: data-win-control="WinJS.UI.AppBarCommand"
16: data-win-options="{label:'Settings', icon:'settings', section:'global'}">
17: </button>
18: </div>
The main difference in this definition is in the way commands are positioned. At the first sight is appear there is not any specification but the "section" property defines two areas in the appbar named "global" and "selection". The name comes from the function of this area. Since the "global" section is for always-available commands and it maps to the right, the "selection" area is for commands that are contextual to the selection. This area maps to the left.
In html and xaml it is possible to define a custom layout that is commonly used for navigation purposes in the top appbar. To understand better the meaning of "navigation" think at the top appbar in Internet Explorer. This area shows the pages that are currently opened in the browser. Here is an example in XAML:
1: <Page.TopAppBar>
2: <AppBar x:Name="topAppBar" IsSticky="False" Background="#FF232323">
3: <ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Hidden">
4: <ItemsControl x:Name="images">
5: <ItemsControl.ItemsPanel>
6: <ItemsPanelTemplate>
7: <StackPanel Orientation="Horizontal" />
8: </ItemsPanelTemplate>
9: </ItemsControl.ItemsPanel>
10: <ItemsControl.ItemTemplate>
11: <DataTemplate>
12: <Button Margin="5,5,5,18" Tag="{Binding}">
13: <Grid>
14: <Image Source="{Binding Uri}" Width="180" Height="135" Stretch="UniformToFill" />
15: <TextBlock Style="{StaticResource TitleTextStyle}"
16: HorizontalAlignment="Right" VerticalAlignment="Bottom"
17: Text="{Binding Title}" Foreground="White" Margin="0,0,0,0" />
18: </Grid>
19: </Button>
20: </DataTemplate>
21: </ItemsControl.ItemTemplate>
22: </ItemsControl>
23: </ScrollViewer>
24: </AppBar>
25: </Page.TopAppBar>
In this example the top appbar contains an horizontal stacked itemscontrol that is wrapped by a scrollviewer. Thanks to this layout the panel shows a selectable and scrollable list of items emulating the behavior of internet explorer. So please don't blame me if I don't show the same in HTML but a similar example would take all the article to be shown and explained. If you are intersted in please visit this page: http://girijashankarbeuria.wordpress.com/2013/06/04/winjs-appbar-tabbed-control-with-listview/ that has a complete example.
Popups vs Flyouts
The AppBar is only the most simple and common alternative place to create more room for functions. When the AppBar does not suffice you can embrace the 3rd dimension and go with Popups and Flyouts. These items have been created to present popup elements and, until the availability of Windows 8.1, they are one for XAML (popups) and the other for HTML (flyouts). When Windows 8.1 will be public, XAML will get also a Flyout controls that has been widely requested. The reason for this request is because Flyout is a control much more effective than Popup. This one infact that requires much more effort in development because its positioning is totally in charge of the developer. With Flyout instead the positioning is handled by the control.
With XAML most of the work is conveniently done in C# also if you can create the popup in xaml. Here you create the Popup instance and then set the position and add some content. In the following snippet I add a Border element just only to make the popup visible. In a real world app, you probably create a user control to add to the popup.
1: private void Button_Click(object sender, RoutedEventArgs e)
2: {
3: Popup popup = new Popup();
4:
5: popup.IsLightDismissEnabled = true;
6:
7: popup.Child = new Border
8: {
9: Width = 200,
10: Height = 200,
11: Background = new SolidColorBrush(Colors.White),
12: BorderThickness = new Thickness(1)
13: };
14:
15: Button b = (Button)sender;
16: var gt = b.TransformToVisual(this.root);
17: Point offset = gt.TransformPoint(new Point(0, 0));
18: popup.HorizontalOffset = offset.X;
19: popup.VerticalOffset = offset.Y - 200 ;
20:
21: popup.IsOpen = true;
22: }
The position of the popup is calculated relatively to a positioned element in this case the button that caused its open. This code is for sure good to get a fine-tuned positioning but most of the times it is redundant and hard to be handled. In HTML the flyout control does most of the work for you.
1: <button class="action" id="theButton">Click me!</button>
2:
3: <div id="theFlyout" data-win-control="WinJS.UI.Flyout">
4: <div>Do you confirm?</div>
5: <button class="action">Yes!</button>
6: </div>
This markup, placed into the page must be activated by code. So in Javascript you attach the button click event and you call the show method. This method requires two parameters, the control to be used to calculate the position and the relative placement, expressed with a string like "top", "bottom", etc...
1: ready: function (element, options)
2: {
3: var theButton = document.getElementById("theButton");
4: var theFlyout = document.getElementById("theFlyout");
5:
6: theButton.addEventListener("click",
7: function(ev)
8: {
9: theFlyout.winControl.show(theButton, "bottom");
10: }, false);
11: },
So, if you are a XAML programmer you have two choices: if you are still on Windows 8 you can download "callisto" and you get a Flyout control very close to the WinJS one, or using Windows 8.1 you work with the new Flyout control.
Popup and Flyouts play an important role in Windows Store Apps, and they are used in a number of places. The most simple case is the confirmation popup that appear close to a button, but most of the times, AppBar commands are decorated with flyouts to tune functions and features. I'm pretty sure you found some of these popups in some apps. The important concept to have in mind is that a popup should be dismissed by simply clicking (or tap) outside of it. The is meaning of the IsLightDismissEnabled flag.
Context Menus
The last surfaces that I would like to speak about are context menus. They are for sure a special case of flyouts but they are handled with a different control. In XAML and in HTML the control is exactly the same and it is called PopupMenu. The popup menu works as a set of UICommands, and the positioning is made relatively to another element like for Flyouts. Here is the C# code:
1: private async void TextBox_ContextMenuOpening(object sender, ContextMenuEventArgs e)
2: {
3: e.Handled = true;
4:
5: if (this.LoremIpsum.SelectionLength > 0)
6: {
7: string first = this.LoremIpsum.SelectedText.Split(' ').FirstOrDefault();
8:
9: PopupMenu menu = new PopupMenu();
10: menu.Commands.Add(new UICommand(first, null, 1));
11: menu.Commands.Add(new UICommandSeparator());
12: menu.Commands.Add(new UICommand("To upper", null, 2));
13: menu.Commands.Add(new UICommand("To lower", null, 3));
14:
15: IUICommand command = await menu.ShowForSelectionAsync(this.LoremIpsum.GetSelectionRect(), Placement.Below);
16:
17: if (command != null)
18: {
19: switch ((int)command.Id)
20: {
21: case 1:
22: break;
23: case 2:
24: this.LoremIpsum.SelectedText = this.LoremIpsum.SelectedText.ToUpper();
25: break;
26: case 3:
27: this.LoremIpsum.SelectedText = this.LoremIpsum.SelectedText.ToLower();
28: break;
29: }
30: }
31: }
32: }
In this example I open the popup close to the selection rectangle of a textbox with bottom placement. The code in Javascript is very similar because the control is part of Windows.UI.Popups instead of WinJS and is in common between both the languages. The calls differs only for name's capitalization.
Have surfaces under control
Make a good usage of the available space in the windows Store apps is important to give an effective experience to your users. Togheter with the "surfaces" I've illustrated in this brief article you can count on multiple other solutions. The same Settings area is another surface to take in serious consideration for its purposes. My suggestion is to always plan carefully the elements, having clear in mind how the user must interact with the application to achieve the expected results.