Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Telerik and Windows Phone 8 – The JumpList (Grouping)

DZone's Guide to

Telerik and Windows Phone 8 – The JumpList (Grouping)

· Mobile Zone
Free Resource

Download this comprehensive Mobile Testing Reference Guide to help prioritize which mobile devices and OSs to test against, brought to you in partnership with Sauce Labs.

Telerik is a very well known company by Microsoft developers, since it develops probably the best components and controls for .NET technologies.  Its relationship with Microsoft developers started a long time ago, since, in their catalogue, you can find controls for “old” technologies like Windows Forms.

It’s a commercial company: their controls suites aren’t free, even if Telerik is a company that has a strong relationships with communities, so it’s not rare to receive free licenses during events and conferences. But, recently, their Windows Phone suite has started to gain a lot of interest among Windows Phone developers for many reasons:

  • The quality of che provided controls is very high: they can make your life easier and they almost fully support binding (even when standard controls doesn’t), so they are a good companion for MVVM apps.
  • Telerik suites, usually, have a high price, because they include all the available controls developed by the company. But, since Windows Phone is gaining a lot of interest also from hobbyst and students, Telerik has decided to sell at 99$ just the Windows Phone controls, without having to buy the full suite: for this reason, the price is affordable also if you’re not a professional.
  • As I’ve already mentioned in this blog, Nokia has created a new program called Nokia Premium Developer which, at the same price of the standard Microsoft Store registration (99 $), it includes a token to create or renew a Store account, a certain number of API calls for the Buddy’s API services and, guess what, a Telerik license!

For these reasons, and due to my recent experience with the suite (I used it in my latest projects), I’ve decided to write some blog posts to show you how to use some of the controls that are part of the toolkit and how they can improve your work.

Le’t start with the JumpList!

The JumpList control

Lists are one of the key part of every Windows Phone application: it’s almost impossible to find an application that doesn’t need to display a collection of data. Originally Windows Phone 7 included just the ListBox control for this scenario, that had many limitations and performance problems. Things are changed now, since Windows Phone 8 includes a control called LongListSelector (that, previously, was part of the Phone Toolkit), that has much better performances and that supports features like grouping and sorting.

But things are still not perfect: the LongListSelector doesn’t support features that are, instead, widely used by the platform itself, like sticky headers or multiple selection. Plus, the approach to group your data is not very simple: it requires to create a separate class to manage them and to change your collection, like it’s described in this MSDN article.

For this reason Telerik has included in the RadControls for Windows Phone suite a control called RadJumpList, which goal is to overcome the limitations of the originalLongListSelector control. Let’s see how to implement some scenarios with theRadJumpList control.

Grouping data

Grouping is one of the features that is widely used also by the native operating system: just think at the People hub, where contacts are grouped by their initial, so that the user can easily jump from a letter to another. The RadJumpList control makes very easy to group your data in the same way and, most important, it doesn’t require you to change your original collection: with the LongListSelector control, in fact, instead of just setting your collection as ItemsSource property of the control, you have first to group your data. WithRadJumpList, instead, you can keep using your original collection, where items are not grouped: grouping will be added in a second step. Let’s start with a simple example: we have a collection of people, that we want to display in the application. Every person is mapped with a specific class:

public class Person
{
    public string Name { get; set; }
    public string Surname { get; set; }
    public string City { get; set; }
}

Let’s start by adding the control in the XAML (you’ll need to declare the following namespace xmlns:telerikDataControls=”clr-namespace:Telerik.Windows.Controls;assembly=Telerik.Windows.Controls.Data” in thePhoneApplicationPage node in the XAML).

<telerikDataControls:RadJumpList x:Name="People">
    <telerikDataControls:RadJumpList.ItemTemplate>
        <DataTemplate>
            <StackPanel>
                <TextBlock Text="{Binding Path=Name}" />
                <TextBlock Text="{Binding Path=Surname}" />
            </StackPanel>
        </DataTemplate>
    </telerikDataControls:RadJumpList.ItemTemplate>
</telerikDataControls:RadJumpList>

As you can see, for the basic use there are no differences with a standard ListBox orLongListSelector: we define an ItemTemplate, which is the template that will be used to show every item of the collection. In this sample, we simply display the Name andSurname properties of the person.

In the code behind, we’re going to load some data as we’ve already used to do with a ListBox:

public MainPage()
{
    InitializeComponent();
 
    // Sample code to localize the ApplicationBar
    //BuildLocalizedApplicationBar();
 
    ObservableCollection<Person> people = new ObservableCollection<Person>
        {
            new Person
                {
                    Name = "Matteo",
                    Surname = "Pagani",
                    City = "Como"
                },
            new Person
                {
                    Name = "Ugo",
                    Surname = "Lattanzi",
                    City = "Milan"
                },
            new Person
                {
                    Name = "Mario",
                    Surname = "Rossi",
                    City = "Milan"
                }
        };
 
    People.ItemsSource = people;
}

Nothing special here: if you launch the application, you’ll see the list of people displayed in the RadJumpList control.

But if we want grouping? We need to interact with the GroupDescriptors property of theRadJumpList control, that can be used to set how we want to group our data. Let’s say we want to group our contacts by city. Here is the code we need to add before setting theItemsSource property of the RadJumpList control.

GenericGroupDescriptor<Person, string> group = new GenericGroupDescriptor<Person, string>();
group.KeySelector = (person) =>
    {
        return person.City;
    };
 
People.GroupDescriptors.Add(group);

Easy, isn’t it? We just need to define a new GenericGropDescriptor<T, Y> object, whereis the base class of our collection (in this case, Person), while Y is the property’s type we want to use for grouping (in our sample, City, that is a string). Then we assign a function to the KeySelector property, that is the way we want to group our data. This function features, as parameter, the object’s type of our collection (in our case, Person), so we simply need to return, as result, the field we want to use for grouping (City). In the end, we add theGenericGroupDescriptor object to the GroupDescriptors collection of the RadJumpListcontrol. And that’s it! Now launch the application and you’ll see your data grouped by city: plus, the group headers will be interactive, so that the user can tap on them and jump directly to the selected group.

jumplist1jumplist2

Sorting

Sorting your data is really easy and RadJumpList supports two way of sorting: by group and by item. The two things can be combined, so that you can have your groups ordered with a criteria and the items inside that group ordered for another one. Sorting the groups is really easy: the GenericGroupDescriptor class we’ve just seen supports a property calledSortMode, that accepts one of the values of the ListSortMode enumerator: Ascending, Descending and None.

GenericGroupDescriptor<Person, string> group = new GenericGroupDescriptor<Person, string>();
group.SortMode = ListSortMode.Ascending;
group.KeySelector = (person) =>
    {
        return person.City;
    };
 
People.GroupDescriptors.Add(group);

This type of sorting applies just to the order in which groups are displayed in the list and it doesn’t affect the elements inside every group: if you try to change, for example, theSortMode to ListSortMode.Descending, you’ll see that the group labeled Milan will be displayed before the one labeled Como, but the order of the contacts inside every group won’t change.

If you want to apply a specific order also for the contacts, you’ll have to use aGenericSortDescriptor<T, Y> object, that works exactly like theGenericGroupDescriptor one. The only difference is that, in this case, as value of theKeySelector property we will pass a function that returns the property we want to use to order the items.

GenericSortDescriptor<Person, string> sort = new GenericSortDescriptor<Person, string>();
sort.SortMode = ListSortMode.Ascending;
sort.KeySelector = person =>
    {
        return person.Name;
    };
 
People.SortDescriptors.Add(sort);

In this sample we want to order the contacts by name: after we’ve set up ourGenericSortDescriptor object, we add it to another special collection exposed by theRadJumpList control, that is called SortDescriptors. This sorting is independant from the grouping one: if you try to change the SortMode to ListSortMode.Descending you’ll notice that the groups order won’t change, but the order of the contacts inside every group will be different.

Grouping and sorting with MVVM

Using grouping and sorting in an application built with the MVVM pattern it’s easy, since the RadJumpList control exposes two properties called GroupDescriptorsSource andSortDescriptorsSource, that support binding. They accept a collection as input, so you’ll have to create in your ViewModel two collections to hold the GenericGroupDescriptor orGenericSortDescriptor criterias you want to apply (even if you’re going to add just one criteria).

Here is a sample of a ViewModel:

public class MainViewModel: INotifyPropertyChanged
{
    private List<GenericGroupDescriptor<Person, string>> groupDescriptors;
 
    public List<GenericGroupDescriptor<Person, string>> GroupDescriptors
    {
        get { return groupDescriptors; }
        set
        {
            groupDescriptors = value;
            OnPropertyChanged("GroupDescriptors");
        }
    }
 
    private List<GenericSortDescriptor<Person, string>> sortDescriptors;
 
    public List<GenericSortDescriptor<Person, string>> SortDescriptors
    {
        get { return sortDescriptors; }
        set
        {
            sortDescriptors = value;
            OnPropertyChanged("SortDescriptors");
        }
    }
 
    public MainViewModel()
    {
        GroupDescriptors = new List<GenericGroupDescriptor<Person, string>>();
        SortDescriptors = new List<GenericSortDescriptor<Person, string>>();
 
        GenericGroupDescriptor<Person, string> group = new GenericGroupDescriptor<Person, string>();
        group.SortMode = ListSortMode.Ascending;
        group.KeySelector = (person) =>
            {
                return person.City;
            };
 
        GroupDescriptors.Add(group);
 
        GenericSortDescriptor<Person, string> sort = new GenericSortDescriptor<Person, string>();
        sort.SortMode = ListSortMode.Ascending;
        sort.KeySelector = person =>
            {
                return person.Name;
            };
 
        SortDescriptors.Add(sort);
    }
 
    public event PropertyChangedEventHandler PropertyChanged;
 
    [NotifyPropertyChangedInvocator]
    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
    }
}

As you can see, we simply use the same code we’ve seen before but, instead of adding the generic descriptors directly to the RadJumpList control, we add them to two collections exposed by the ViewModel. Then, in the XAML, we use binding to connect them to theRadJumpList control:

<telerikDataControls:RadJumpList x:Name="People" GroupDescriptorsSource="{Binding Path=GroupDescriptors}" SortDescriptorsSource="{Binding Path=SortDescriptors}">
    <telerikDataControls:RadJumpList.ItemTemplate>
        <DataTemplate>
            <StackPanel>
                <TextBlock Text="{Binding Path=Name}" />
                <TextBlock Text="{Binding Path=Surname}" />
            </StackPanel>
        </DataTemplate>
    </telerikDataControls:RadJumpList.ItemTemplate>
</telerikDataControls:RadJumpList>

In the next posts

In the next posts we’ll see some other features of the RadJumpList control: how to use sticky headers, multiple selection and how to customize grouping. Meanwhile, you can play with the sample project (obviously, the Telerik libraries are missing, since they can’t be redistributed, you’ll need to manually add your own ones).





Analysts agree that a mix of emulators/simulators and real devices are necessary to optimize your mobile app testing - learn more in this white paper, brought to you in partnership with Sauce Labs.

Topics:

Published at DZone with permission of Matteo Pagani, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}