Telerik and Windows Phone 8 – The JumpList (Multi selection)

We continue our journey to see how to use some of the most interesting features of the RadJumpList, one of the available controls in the RadControls for Windows Phone toolkit developed by Telerik.

Multi selection

Multi selection is a simple but interesting feature that will allow the user to choose more than one element from the list, by checking the checkboxes that are displayed on the left of the item. By default, selection isn’t enabled: the RadJumpList control will behave like a standard list; when the user taps on an item, you can intercept it and implement your own logic (for example, you can redirect the user to a detail page to see the details of the selected item.

The first step to enable it is to set the IsCheckModeEnabled property to True and you can do it in the XAML or in the code. Once it’s enabled, you’ll notice that the left margin of the items will be greater, but the list will continue to work as usual.

You have two ways to effectively enable multi selection mode:

  • You can tap on the left of any item: multi selection will be activated and you’ll see the checkboxes appear.
  • You can set the IsCheckModeActive property of the RadJumpList control to True: this way, you can also enable the multi select mode in the code if, for example, you want to provide a button for this purpose. The native Mail app shows an example of this behavior: you can enable multi select mode by tapping on the left of any item or by using the appropriate button in the Application Bar.

By default, if you’ve enable grouping like we’ve seen in the previous post, user will be allowed also to select groups and not only single items. If you want to disable this behavior, you need to set the GroupCheckMode to None: this way, checkboxes will be displayed only next to the single items.

Here is a sample of a RadJumpList control with multi selection enabled:

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

Managing the selected items is really simple: the RadJumpList control exposes a property called CheckedItems, which contains the collection of items that have been selected. Here is a really sample code that can be used to show the number of items that have been selected by the user.

private void OnShowItemsClicked(object sender, RoutedEventArgs e)
{
    MessageBox.Show(People.CheckedItems.Count.ToString());
}

Supporting multi selection with MVVM

One issue of the RadJumpList control is that, at the moment, CheckedItems doesn’t support binding, so you can’t have a property in your ViewModel with the collection of the items that have been selected. The best workaround I’ve found and that I’m using in my Speaker Timer app is to use a custom behavior, that has been developed by my dear friend Marco Leoncini. The purpose of this behavior is to automatically store, in a property of the ViewModel, the list of selected items.

First, you need to define in your ViewModel a collection, that will hold the items that will be checked by the user. For the following samples, I’m going to use the helpers provided by the MVVM Light Toolkit by Laurent Bugnion, that you can install using NuGet. Here is a ViewModel sample:

public class MultiSelectViewModel : ViewModelBase
{
    private ObservableCollection<Person> people;

    public ObservableCollection<Person> People
    {
        get { return people; }
        set
        {
            people = value;
            RaisePropertyChanged("People");
        }
    }

    private ObservableCollection<Person> itemsToDelete;

    public ObservableCollection<Person> ItemsToDelete
    {
        get { return itemsToDelete; }
        set
        {
            itemsToDelete = value;
            RaisePropertyChanged("ItemsToDelete");
        }
    }


    public MultiSelectViewModel()
    {
        ItemsToDelete = new ObservableCollection<Person>();
    }
}

In this sample, ItemsToDelete is the property that will store the items selected by the user (this sample is taken from my Speaker Timer app, where multi selection is enabled to delete one or more sessions). The second step is to create a new class, that will contain our behavior:

public class AddoToCheckedItemBehavior : Behavior<RadDataBoundListBox>
{
    public AddoToCheckedItemBehavior() { }

    protected override void OnAttached()
    {
        base.OnAttached();
        this.AssociatedObject.ItemCheckedStateChanged += AssociatedObject_ItemCheckedStateChanged;
    }

    void AssociatedObject_ItemCheckedStateChanged(object sender, ItemCheckedStateChangedEventArgs e)
    {
        var viewModel = ((FrameworkElement)sender).DataContext as MainPageViewModel;
        if (viewModel == null) return;
        if (e.IsChecked)
        {
            viewModel.ItemsToDelete.Add(((Telerik.Windows.Data.IDataSourceItem)e.Item).Value as Session);
        }
        else { viewModel.ItemsToDelete.Remove(((Telerik.Windows.Data.IDataSourceItem)e.Item).Value as Session); }
    }

    protected override void OnDetaching()
    {
        base.OnDetaching();
        this.AssociatedObject.ItemCheckedStateChanged -= AssociatedObject_ItemCheckedStateChanged;
    }
}

The purpose of this behavior is very simple: it inherits from the Behavior<RadJumpList> class (so that it can be used in combination with a RadJumpList control) and it subscribes to the ItemCheckedStateChanged event, that is triggered every time the user checks or unchecks an item from the list. When this event is triggered, we get a reference to the current ViewModel and we add or remove the selected item from the ItemsToDelete collection. To do this, we use a property returned by the event handler’s parameter: the e object (which type is ItemCheckedStateChangedEventArgs) contains the properties Item (which is the selected item) and IsChecked (which is a boolean, that tells you if the item has been checked or unchecked).

There’s space for improvements in this behavior: one limitation is that it works just for our specific ViewModel, since when we get the reference to the ViewModel associated to the current view (using the DataContext property) we cast it to the MainViewModel class. If we need to apply the same behavior to multiple RadJumpList controls in different page, we can create a base class which our ViewModels can inherit from. This base class will host the the ItemsToDelete property, so that every ViewModel will be able to use it. This way, we can change the cast from MainViewModel to our new base class and reuse the same behavior for different ViewModels.

How to apply the behavior? First, we need to add a reference to the System.Windows.Interactivity library, that is available by clicking with the right click on your project and choosing Add new reference: you’ll find it in the Assemblies, Extensions sections.

After that, you can add the behavior directly in the XAML, by declaring the following namespace (plus the namespace of the behavior’s class you’ve created):

xmlns:i=”clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity”

<telerikDataControls:RadJumpList IsCheckModeEnabled="True" GroupCheckMode="None" ItemsSource="{Binding Path=People}">
    <telerikDataControls:RadJumpList.ItemTemplate>
        <DataTemplate>
            <StackPanel>
                <TextBlock Text="{Binding Path=Name}" />
                <TextBlock Text="{Binding Path=Surname}" />
            </StackPanel>
        </DataTemplate>
    </telerikDataControls:RadJumpList.ItemTemplate>
    <i:Interaction.Behaviors>
        <behaviors:AddoToCheckedItemBehavior />
    </i:Interaction.Behaviors>
</telerikDataControls:RadJumpList>

Now in the ViewModel, automatically, the ItemsToDelete property will always contain the items that have been checked by the user, so that you can use them for your own needs. In the following sample, we define a command to simply show a message with the number of selected items:

private RelayCommand showCount;

 public RelayCommand ShowCount
 {
     get
     {
         if (showCount == null)
         {
             showCount = new RelayCommand(() =>
                                              {
                                                  MessageBox.Show(ItemsToDelete.Count.ToString());
                                              });
         }
         return showCount;
     }
 }

Happy coding! As usual, remember that the sample project doesn’t contain the Telerik libraries, since we’re talking about a commercial suite.

This entry was posted in Windows Phone and tagged , . Bookmark the permalink.

6 Responses to Telerik and Windows Phone 8 – The JumpList (Multi selection)

  1. FENI says:

    If i want to remove the specific item from jump list selector control in windows phone 8 then what to do? I mean i have implemented that how items gonna be removed from long list selector control its working fine with the below code, CommonClass.conper.Remove(((Model.Model)llist.SelectedItem)); where conper is a observable collection which contains name,number& image but when i am going to implement then it removes item from long list selector control but it wont remove items form jump list selector control. if u got the idea then plz help me ASAP.

    • qmatteoq says:

      Hi, your problem is not totally clear to me. You’re saying that you’re removing an item from the list but, if it’s the only one that is part of a group, that group is not removed?

      • FENI says:

        Thanks For Reply,
        My Question is Simple :
        How To Remove Items From Jump List Selector Control ?

        • qmatteoq says:

          Simply remove the item from the collection that is in binding with the Jump List control. If you’re using an ObservableCollection, the modify will automatically update the Jump List control.
          Something like:


          MyCollection.Remove(item);

  2. Michael Giger says:

    Hi
    Thanks for the sample!
    I found a other way 🙂 The RadJumpList has a propery named “ItemCheckedPath”. Add a boolean property such as “IsSelected” to the object that you bind at ItemsSource and set ItemCheckedPath=”IsSelected”. It works fine 🙂

    http://www.telerik.com/help/windows-phone/raddataboundlistbox-features-multiselection-itemcheckedpath.html

Leave a Reply