Alphabet Flashcards (Filmstrip-Style Swiping)

0
192

Someone recently asked me how to build a flashcard app where the user could swipe between cards, much like when navigating a strip of photos in the Pictures hub or in the Facebook app. For lack of a better term, I’m referring to this as a filmstrip user experience.

It occurred to me that there’s currently no simple panel or other element for performing this type of interaction. A simple scroll viewer doesn’t work as-is because you want each item to be “magnetic” and not allow the view to rest in an unaligned position.

Although the pivot and panorama controls are much more feature-filled than what’s required for this task, they provide the easiest way to create this kind of user interface. You just need to hide the title and header and make some layout tweaks. A pivot is better suited for dynamic items, thanks to its LoadingPivotItem and UnloadingPivotItem events, but a panorama is a bit better suited for faithfully mimicking a filmstrip, as it enables you to see the next or previous item in the midst of a swipe.

Therefore, Alphabet Flashcards uses a panorama to provide filmstrip-style browsing of a set of 26 flashcards, one for each letter of the alphabet. A parent can use this with a toddler to practice learning letters.

The User Interface

Alphabet Flashcards uses a single panorama-filled page with 27 panorama items: one for each letter in the alphabet and one that acts like a title page. Figure 28.1 shows the experience of swiping from the first item (the title page) to the second item (the letter A).

Swiping from the first panorama item to the second panorama item.
FIGURE 28.1 Swiping from the first panorama item to the second panorama item.

To get the illusion of a full-screen filmstrip experience, the panorama used by this page and its items do not use any title or headers. The items also use a slight negative top margin to consume space that would be wasted.

The right-most 48 pixels of the control are reserved for a 12-pixel margin between items and a 36-pixel preview of the next item’s left side. Because we don’t want the preview behavior in this app, we simply ensure the content in each item has a 36-pixel left margin. Besides keeping the next item off-screen until swiping begins, this also keeps the content centered. It does, however, force the content to have a maximum width of 384 in the portrait orientation (480 – 48×2). Figure 28.2 demonstrates this more clearly by giving the panorama an orange background, the first item a green background, the second item a blue background, and the third item a purple background.

Listing 28.1 contains the XAML for this page.

FIGURE 28.2 The same sequence as in Figure 28.1, but showing where each item—and its inner content—begins and ends.
FIGURE 28.2 The same sequence as in Figure 28.1, but showing where each item—and its inner content—begins and ends.

LISTING 28.1 MainPage.xaml—The User Interface for Alphabet Flashcards’Main Page

[code]

<phone:PhoneApplicationPage x:Class=”WindowsPhoneApp.MainPage”
xmlns=”http://schemas.microsoft.com/winfx/2006/xaml/presentation”
xmlns:x=”http://schemas.microsoft.com/winfx/2006/xaml”
xmlns:phone=”clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone”
xmlns:controls=”clr-namespace:Microsoft.Phone.Controls;
➥assembly=Microsoft.Phone.Controls”
SupportedOrientations=”Portrait”>
<Grid Background=”White”>
<controls:Panorama x:Name=”Panorama”>
<controls:Panorama.ItemTemplate>
<DataTemplate>
<Grid Margin=”36,-24,0,0”>
<Image Source=”{Binding}”/>
</Grid>
</DataTemplate>
</controls:Panorama.ItemTemplate>
<controls:Panorama.HeaderTemplate>
<!– Make sure the header is empty –>
<DataTemplate><Canvas/></DataTemplate>
</controls:Panorama.HeaderTemplate>
</controls:Panorama>
</Grid>
</phone:PhoneApplicationPage>

[/code]

  • Rather than giving the panorama 27 items in XAML, the code-behind sets its ItemsSource to an array of image URI strings. The panorama uses an item template to render each image inside a grid with a margin needed to get the effect shown in Figure 28.1.
  • When a panorama contains something other than a PanoramaItem control, such as the strings used by this app, each item’s main content and header displays the item. Therefore, Listing 28.1 must explicitly set each item’s HeaderTemplate to something blank to avoid each URI being rendered in a text block on top of each image.
  • The images used in this app are marked with a Build Action of Resource, so the panorama does not appear until the images are ready.

The Code-Behind

Listing 28.2 contains the code-behind for the main page. Besides filling the panorama with items, it persists and restores the selected item, so the app can resume where it left off.

LISTING 28.2 MainPage.xaml.cs—The Code-Behind for Alphabet Flashcards’Main Page

[code]

using System.Windows.Navigation;
using Microsoft.Phone.Controls;
namespace WindowsPhoneApp
{
public partial class MainPage : PhoneApplicationPage
{
// Persist the selected item
Setting<int> selectedIndex = new Setting<int>(“SelectedIndex”, 0);
public MainPage()
{
InitializeComponent();
this.Panorama.ItemsSource = new string[] {
“Images/title.png”,
“Images/a.png”,
“Images/b.png”,
“Images/c.png”,

“Images/x.png”,
“Images/y.png”,
“Images/z.png”
};
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
// Restore the selected item
this.Panorama.DefaultItem = this.Panorama.Items[this.selectedIndex.Value];
}
protected override void OnNavigatedFrom(NavigationEventArgs e)
{
base.OnNavigatedFrom(e);
// Remember the selected item
this.selectedIndex.Value = this.Panorama.SelectedIndex;
}
}
}

[/code]

Here, DefaultItem is used exactly how it was designed to be used. The problems with DefaultItem discussed in the preceding chapter aren’t problematic in this app because there is no distinguishable panorama title or background.

The Finished Product

Alphabet Flashcards (Filmstrip-Style Swiping)