Visually Located

XAML and GIS

Migrating from the LongListSelector to the ListView in Windows Phone XAML Apps

The new Windows Phone 8.1 SDK comes with support for Silverlight and XAML based apps. If you built an app with the Silverlight Phone SDK, you probably used the LongListSelector. This control was released with the Windows Phone 8 SDK for Silverlight Phone apps. This control is still available if you are building Windows Phone 8.1 apps if you are using the Silverlight controls. If you want to build a Universal app or just an app based on the XAML stack, The LongListSelector is not available. Instead, we have the ListView control.

Moving to the ListView is really easy, provided you did not use the jump list functionality of the LLS. If you did not have a jump list, moving your app over is as simple as replacing ‘phone:LongListSelector’ with ‘ListView’. The LongListSelector was not in the default namespace, whereas the ListView is so there is no need for a namespace prefix.

<!-- OLD -->
<phone:LongListSelector ItemsSource="{Binding MyItems}"
                        toolkit:TiltEffect.IsTiltEnabled="True">
    <phone:LongListSelector.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding Title}" Style="{StaticResource PhoneTextLargeStyle}">
        </DataTemplate>
    </phone:LongListSelector.ItemTemplate>
</phone:LongListSelector>
 
<!-- NEW -->
<ListView ItemsSource="{Binding MyItems}">
    <ListView.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding Title}" Style="{StaticResource PhoneTextLargeStyle}">
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

Notice the ListView also did not need the TitlEffect from the toolkit. That is because it is built into the ListView. As you can see, moving over is really easy. Now lets look at the jump list functionality and differences in the two controls. Jump list functionality requires two key pieces.

The style for the group headers of the section

image

And the style for the jump list itself.

image

The LLS has both the group header and the jump list functionality built in. The ListView has the ability to display group headers, but not the jump list. Moving the group header functionality over is pretty simple. The LLS had the GroupHeaderTemplate, and the ListView has the GroupStyle.

For the rest of the blog, I’ll take the MSDN example of How to display data in a grouped list in LongListSelector for Windows Phone 8.

<!--OLD -->
<phone:LongListSelector
  GroupHeaderTemplate="{StaticResource AddrBookGroupHeaderTemplate}"
  ItemTemplate="{StaticResource AddrBookItemTemplate}"
  IsGroupingEnabled="true"
  HideEmptyGroups ="true"/>
 
<!-- NEW -->
<ListView ItemsSource="{Binding Source={StaticResource AddressGroups}}"
          ItemTemplate="{StaticResource AddrBookItemTemplate}">
    <ListView.GroupStyle>
        <GroupStyle HidesIfEmpty="True" 
                    HeaderTemplate="{StaticResource AddrBookGroupHeaderTemplate}"/>
    </ListView.GroupStyle>
</ListView>

When grouping items in a LLS you had to set the IsGroupingEnabled to true. When you do this, it tells the LLS that the ItemsSource is of type IEnumerable<IEnumerable<T>. It then knows that the ItemTemplate should not be used to display the items of the bound collection. Instead the ItemTemplate should be used to display the items in the collection of each item of the bound source. The ListView does not have a property that will tell it that it should display items within a collection of each item of the bound source. Instead, you should use a CollectionViewSource. The CollectionViewSource does have the IsSourceGrouped property. This works the same way as the IsGroupingEnabled property.

<Page.Resources>
    <CollectionViewSource x:Key="AddressGroups"
                          IsSourceGrouped="True"/>
</Page.Resources>
<Grid>
    <ListView ItemsSource="{Binding Source={StaticResource AddressGroups}}"
              ItemTemplate="{StaticResource AddrBookItemTemplate}">
        <ListView.GroupStyle>
            <GroupStyle HidesIfEmpty="True" HeaderTemplate="{StaticResource AddrBookGroupHeaderTemplate}"/>
        </ListView.GroupStyle>
    </ListView>
<Grid>

The ListView does not have GroupHeaderTemplate or the HideEmptyGroups property like the LLS. Instead it uses a GroupStyle. A GroupStyle displays the header of the group through the HeaderTemplate property and hiding groups though the HidesIfEmpty property. We are able to reuse our templates for both the items in the list as well as the group headers! This is pretty cool.

So now we have our ListView grouped

imageimage

Now we need a jump list. Again, this was built into the LLS. For Windows Phone XAML apps, you must use the SemanticZoom control. This control was introduced with Windows 8 Store apps. It allows you to set a control to display when it is zoomed in, and one for when it is zoomed out. In Windows Store [tablet] apps, you could pinch to zoom out, or tab a header element to get to a jump list control. The People app is a great example of the SemanticZoom control.

image

<SemanticZoom>
    <SemanticZoom.ZoomedInView>
        <!-- Elment to display when "zoomed in". Usually a ListView or GridView -->
    </SemanticZoom.ZoomedInView>
    <SemanticZoom.ZoomedOutView>
        <!-- Element for jump list, usually a GrivView or ListView -->
    </SemanticZoom.ZoomedOutView>
</SemanticZoom>

For Windows Phone, this control is also used to display jump lists as well. With the LLS, you would set the Style of the control to use when in jump list mode. This would be another LLS that would display either in list mode or grid mode. In XAML apps, you set the actual control to use. For our address book we will use the GridView for the jmp list style, or the zoomed out view of the SemanticZoom. The ListView that we built will be used for the ZoomedInView.

<Page.Resources>
    <DataTemplate x:Key="AddrBookJumpTemplate">
        <Border Padding="5">
            <Border Background="{Binding Converter={StaticResource BackgroundConverter}}" 
                    Width="82" Height="82" HorizontalAlignment="Left">
                <TextBlock Text="{Binding Group.Key}" 
                           Foreground="{Binding Converter={StaticResource ForegroundConverter}}" 
                           FontSize="48" Padding="6" 
                           HorizontalAlignment="Left" VerticalAlignment="Center"/>
            </Border>
        </Border>
    </DataTemplate>
    <!-- other templates -->
</Page.Resources>
 
 
<SemanticZoom>
    <SemanticZoom.ZoomedInView>
        <ListView ItemsSource="{Binding Source={StaticResource AddressGroups}}"
                  ItemTemplate="{StaticResource AddrBookItemTemplate}">
            <ListView.GroupStyle>
                <GroupStyle HidesIfEmpty="True" HeaderTemplate="{StaticResource AddrBookGroupHeaderTemplate}"/>
            </ListView.GroupStyle>
        </ListView>
    </SemanticZoom.ZoomedInView>
    <SemanticZoom.ZoomedOutView>
        <GridView Background="Black" 
              ItemsSource="{Binding Source={StaticResource AddressGroups}, Path=CollectionGroups}"
              ItemTemplate="{StaticResource AddrBookJumpTemplate}">
        </GridView>
    </SemanticZoom.ZoomedOutView>
</SemanticZoom>

We need a different template for the jump list than what was used with the LLS. Most of the changes have to do with the size of the squares used. The ItemsSource for the GridView will use the same CollectionViewSource that the ListView uses, but must bind to the CollectionGroups property of the View. The CollectionGroups is only the groups for the source. It is the top level collection.

We now have our jump list complete! The first image is the jump list built with the LLS while the second is the ListView.

LongListSelectorListView

Download a complete sample including getting the complete WP8 Silverlight sample working in WP8.1 XAML apps.

blog comments powered by Disqus