Rethinking iOS table views

[This article is for Windows 8.x and Windows Phone 8.x developers writing Windows Runtime apps. If you’re developing for Windows 10, see the latest documentation]

You are used to working with UITableView in iOS, so here's how to do data binding with similar controls in Windows Store apps.

The following video compares table views in iOS to list views in Windows Store apps.

In iOS, table views are used to display lists of data, such as a list of contacts, to-dos or shopping items. Here's how to leverage your iOS app-building skills to create lists of data in Windows Store apps for Windows 8 using the ListView and GridView controls. We'll discuss list views in Windows Store apps, and compare them with the iOS UITableView controls used to organize data as lists or as master-detail views. The data used by these controls may be part of the apps, or may be obtained from local or remote databases or downloaded from the web.

Overview of iOS table views

In iOS, table views are often used to display such lists of data. Table views are one of the most commonly used user interface controls in iOS apps. Table views provide a single vertically-scrolling column of items that may be divided in sections. Table views have many uses, such as:

  • To display indexed lists of items
  • To navigate through hierarchically-structured data using lists of items
  • To organize data in visually distinct groupings

Here is a simple table view in iOS that shows a list of items.

Table views are often used in master-detail list programming. They are used in conjunction with split views to show a list of items with the ability to drill down into details of each item as shown here:

ListViews in Windows Store apps

The Windows 8 controls library provides the ListView and GridView controls that you can use to display lists of data. The ListView control is a versatile control that can be customized to display items as a list or a grid. Here is an example of a ListView control being used to show a scrollable list of items:

ListView and GridView controls can source their data from a static in-memory list, a local or remote database, an XML document, a remote web service, or a feed. The ListView control can be associated with the data sources using a technique called data binding. Data binding provides an easy way for Windows Store apps to display, add, delete, or manage data. For additional details, see Data binding overview and Data binding controls.

ListView controls can also be used to display master-detail lists as shown here. The list of items is shown using the ListView control in the left-hand side, and the details are shown using Label controls in the right-hand side. The panels used to show the master list and details can be programmed in a number of different ways including GridView or StackPanel controls.

Unlike the iOS UITableView, the ListView control can also be used to display items in a grid to make better use of the available real estate. The list items shown previously are laid out in a grid with consecutive items placed one below another. The number of rows in a column can be specified to control the layout of the grid, like this.

For more information, see Quickstart: adding ListView and GridView controls and Quickstart: Defining layouts.

Comparing list design in iOS and Windows Store apps

If you have been using UITableView for implementing list views in iOS, you will find that similar functionality is provided by the ListView control in Windows Store apps for Windows 8. The following table enumerates the various steps needed to implement a ListView control in your app. It shows how those steps can be accomplished in both iOS and in Windows 8. You can see that there is a close mapping between the steps in iOS with those in Windows 8.

Steps iOS Windows 8
Create the UI control. Use UITableView. Use theListView class. For more info, see How to add a list view.
Define the list’s look and feel. Use UITableViewPlain or UITableViewGrouped. Define the layout setting the ListView control’s ItemsPanel property using the ItemsPanelTemplate class. Group items in the ListView for a grouped layout. For more information, see Quickstart: adding ListView and GridView controls. For a grouped layout, see How to group items in a list or grid.
Define the items' look and feel. Use UITableViewCellStyle for fixed styles. For a custom layout, define a custom view for the cell. Define the ItemsControl class's ItemTemplate property for the look and feel of each item. For more information, seeQuickstart: adding ListView and GridView controls.
Data bind the control to a data source. Implement UITableViewDelegate interface in the controller. Set the ItemsSource property of the ListView control to a collection of items. For a grouped list, set the ItemsSource property to a CollectionViewSource class instance. For more information, see Quickstart: adding ListView and GridView controls. For a grouped list, see How to group items in a list or grid.

 

ListView Sample

Now we'll build a simple Windows Store app that uses the ListView control to show a list of photos. The original iOS app is shown here. It uses UITableView with the UITableViewCellStyleSubtitle style for the table cells. The cell style allows display of a title, a subtitle, and an image.

Here’s what the equivalent Windows Store app looks like:

Building the app

Here are the high-level steps needed to create this app.

Here is how to build a simple app using a data bound ListView.

  • Create the app.

    In this sample, we are going to create our app using the C# Blank App template.

    • Start Microsoft Visual Studio.
    • On the File menu, click New Project.
    • If Windows Store is not already selected, expand Installed > Templates > Visual C#, and click Windows Store.
    • If Blank App (XAML) is not already selected, click it.
    • In the Name and Location boxes, type a name for the app (such as Space Photos) and a location, or leave the defaults as-is.
    • Click OK.
  • Define the data source.

    Windows 8 allows a variety of data sources to be used in the app. In this app, we will use data defined in the program and instantiated in memory. For information about how to use other data sources, refer to Data binding overview.

    Our app is a photo gallery app that shows the photo, title, and description of each photo. To define the data source, we first define a class to create a list of our items, as shown in the code here.

    • On the Project menu, click Add Class.

    • In the Name box, replace the default text with Photo.cs.

    • Click OK.

    • At the top of the file, add the following using statements:

      using Windows.UI.Xaml.Media;

      using Windows.UI.Xaml.Media.Imaging;

    • Replace the code class Photo { } with the code shown here:

      public class Photo
      {
      
          public Photo(string title,  string description, string imagePath, string category)
          {
              this.Title = title;
              this.Description = description;
              this._imagePath = imagePath;
              this.Category = category;
          }
          public string Title{ get; set; }
          public string Description{ get; set; }
          public string Category { get; set; }
          private ImageSource _image = null;
          private String _imagePath = null;
          public ImageSource Image
          {
              get
              {
                  if (this._image == null && this._imagePath != null)
                  {
                      this._image = new BitmapImage(new Uri(this._imagePath));
                  }
                  return this._image;
              }
          }
      }
      

      In the MainPage.xaml.cs file’s constructor, we create a list of photos that will act as a data source for our ListView control, as shown in the code here.

      • In Visual Studio, in the Solution Explorer window, expand MainPage.xaml, and double-click MainPage.xaml.cs.

      • In the MainPage class, before the MainPage method, add this line of code:

        private List<Photo> photos = new List<Photo>();

      • In the MainPage method, before the line of code

        this.InitializeComponent();

        add the rest of the code shown here.

        Photo photo1 = new Photo("The Cat's Eye Nebula", "Cat's Eye Nebula (NGC 6543) is revealed in this detailed view from NASA's Hubble Space Telescope.",
            "http://www.nasa.gov/images/content/64883main_image_feature_211_jw4.jpg", "Nebula");
        photos.Add(photo1);
        Photo photo2 = new Photo("Chaos at the Heart of Orion", "The chaos that baby stars are creating 1,500 light years away in a cosmic cloud called the Orion nebula.",
            "http://www.nasa.gov/images/content/162283main_image_feature_693_ys_4.jpg", "Nebula");
        photos.Add(photo2);
        Photo photo3 = new Photo("An Eyeful of Saturn", "Saturn and its rings completely  in this natural color image taken on March 27, 2004.", 
            "http://www.nasa.gov/images/content/59802main_pia05389-516.jpg", "Planets");
        photos.Add(photo3);
        Photo photo4 = new Photo("Jupiter Gets a Close-up", "NASA's Cassini spacecraft took this true color mosaic of Jupiter.",
            "http://www.nasa.gov/images/content/53254main_MM_image_feature_97_jw4.jpg", "Planets");
        photos.Add(photo4);
        Photo photo5 = new Photo("A Long Way From Home", "This image of the Earth and moon in a single frame was recorded by Voyager 1 ",
            "http://www.nasa.gov/images/content/151232main_image_feature_601_ys_4.jpg", "Earth/Moon");
        photos.Add(photo5);
        Photo photo6 = new Photo("Milky Way Neighbor", "Our Sun and solar system are embedded in a broad pancake of stars deep within the Milky Way galaxy.",
            "http://www.nasa.gov/images/content/63375main_image_feature_202_jw4.jpg", "Galaxy");
        photos.Add(photo6);
        Photo photo7 = new Photo("Moon Aglow", "Framed by the Earth's horizon and airglow, the full moon floats in the blackness of space .",
            "http://www.nasa.gov/images/content/111199main_image_feature_290_ys4.jpg", "Earth/Moon");
        photos.Add(photo7);
        

        The list of photos of type List<Photo> is a defined as a C# generic list. For more information, refer to An Introduction to C# Generics.

        • Add a ListView control to the page. Add a ListView control to your app using Extensible Application Markup Language (XAML) code as follows. In Visual Studio, in the Solution Explorer window, double-click MainPage.xaml.

        • Replace the lines of code

          <Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}"></Grid>

          with the code shown here.

          // Windows 8
          <StackPanel Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
              <TextBlock Text="NASA/JPL Photos" Style="{StaticResource HeaderTextStyle}"></TextBlock>
              <ListView x:Name="photoListView" ItemsSource="{Binding}" >
              </ListView>
              </StackPanel>
          
          // Windows 8.1
          <StackPanel Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
              <TextBlock Text="NASA/JPL Photos" Style="{StaticResource HeaderTextBlockStyle}"></TextBlock>
              <ListView x:Name="photoListView" ItemsSource="{Binding}" >
              </ListView>
              </StackPanel>
          

          The data binding is created in XAML using the {Binding..} syntax. The source of binding is created by setting the DataContext property of the ListView control. The ItemsSource attribute with the value {Binding} specifies that the list's items are data bound to the DataContext property of the ListView control itself. For more information on data binding see Data binding overview.

          You could also add the ListView control to your app programmatically. For details, see Quickstart: adding controls and handling events.

    • Design the look and feel of the list.

      We will use the default look and feel of the list view, that is, as a scrollable list, which is similar to the look and feel of lists in iOS. For more information on changing the look and feel of the list, see Quickstart: adding ListView and GridView controls.

    • Design the look and feel of the items in the list.

      In Visual Studio, in the MainPage.xaml file, between the opening tag <ListView x:Name="photoListView" ItemsSource="{Binding}"> and the closing tag </ListView>, add this XAML code:

      // Windows 8
      <ListView.ItemTemplate>
          <DataTemplate>
              <Grid Height="110" Margin="6">
                  <Grid.ColumnDefinitions>
                      <ColumnDefinition Width="Auto"/>
                      <ColumnDefinition Width="*"/>
                  </Grid.ColumnDefinitions>
                  <Image Source="{Binding Image}" Stretch="UniformToFill" Grid.Column="0"  Width="110" Height="110"/>
                  <StackPanel Grid.Column="1" VerticalAlignment="Top" Margin="10,0,0,0">
                      <TextBlock Text="{Binding Title}" Style="{StaticResource TitleTextStyle}" TextWrapping="NoWrap"/>
                      <TextBlock Text="{Binding Description}" Style="{StaticResource BodyTextStyle}" MaxHeight="60"/>
                  </StackPanel>
              </Grid>
          </DataTemplate>
      </ListView.ItemTemplate>
      
      // Windows 8.1
      <ListView.ItemTemplate>
          <DataTemplate>
              <Grid Height="110" Margin="6">
                  <Grid.ColumnDefinitions>
                      <ColumnDefinition Width="Auto"/>
                      <ColumnDefinition Width="*"/>
                  </Grid.ColumnDefinitions>
                  <Image Source="{Binding Image}" Stretch="UniformToFill" Grid.Column="0"  Width="110" Height="110"/>
                  <StackPanel Grid.Column="1" VerticalAlignment="Top" Margin="10,0,0,0">
                      <TextBlock Text="{Binding Title}" Style="{StaticResource TitleTextBlockStyle}" TextWrapping="NoWrap"/>
                      <TextBlock Text="{Binding Description}" Style="{StaticResource BodyTextBlockStyle}" MaxHeight="60"/>
                  </StackPanel>
              </Grid>
          </DataTemplate>
      </ListView.ItemTemplate>
      

      To specify the look and feel of items in the list, we need to set the ItemsTemplate property of the ListView control specifying a DataTemplate object, using XAML code. (For additional information, refer to Quickstart: adding ListView and GridView controls.) The controls in the layout can be bound to properties of a data object or have content defined inline.

      We have defined the template for the items in the ListView inline. The template consists of a grid where in the left column we show the photo. And in the right column, we will show title of the image along with its description below it. The title and description are shown one below the other.

      The Source property of the Image object is specified as {Binding Image} which binds it to the Image property of the item's backing Photo object. Similarly, the two TextBlock controls are bound to the Title and Description properties, respectively, of the item's backing Photo object.

      When using Windows 8, the style of the two TextBlock controls is defined using two statically-defined styles, namely, TitleTextStyle and BodyTextStyle. These styles' definitions can be found in the project's StandardStyles.xaml file (to view this file, in the Solution Explorer window, expand the Common folder, and double-click StandardStyles.xaml).

      When using Windows 8.1, the StandardStyles.xaml file is no longer present and instead the built-in styles TitleTextBlockStyle and BodyTextBlockStyle should be used. See Windows 8 to Windows 8.1 Preview starting with the XAML templates.

    • Setting the item source.

      Once our item list is created, setting item source is quite simple. In Visual Studio, in the MainPage.xaml.cs file, in the OnNavigatedTo method, add the code shown here.

       protected override void OnNavigatedTo(NavigationEventArgs e) 
              {
                  photoListView.ItemsSource = photos;
              }
      

Using the ListView control in a grid layout

In Visual Studio, in the MainPage.xaml file, between the opening tag <ListView x:Name="photoListView" ItemsSource="{Binding}"> and the closing tag </ListView>, add this XAML code:

<ListView.ItemsPanel>
        <ItemsPanelTemplate>
            <WrapGrid Orientation="Vertical" MaximumRowsOrColumns="-1" />
        </ItemsPanelTemplate>
    </ListView.ItemsPanel>

This defines the ListView layout as a WrapGrid control in a vertical orientation. The value of -1 for the MaximumRowsOrColumns property is a special value that indicates no maximum. This means that as many items will displayed vertically as will fit the height of the ListView control.

Grouped Layout of List View

Similar to iOS grouped table view, ListView control also provides the ability to group items as shown here. Photos are grouped according to the category of photos, namely, Earth/Moon, Galaxies, Nebulae, or Planets. For more information on grouped layout of lists, see How to group items in a list or grid.

Topics for iOS devs

Resources for iOS devs

Windows 8 controls for iOS devs

Windows 8 cookbook for iOS devs

List and grid view topics

Quickstart: adding ListView and GridView controls

How to add a list view

Making a simple UITableView-like list in Windows 8.1

How to group items in a list or grid

Quickstart: Defining layouts

ListView class

Data binding overview

Windows 8 to Windows 8.1 Preview starting with the XAML templates