Implementing LongListSelector as JumpLists in Windows Phone 8 : Creating Custom Jump Lists

At the end of my previous blog post, we have successfully implemented an alphabetically arranged JumpList. In this post, we will see how to customize the JumpList to any other category you would like to use. To do this, we will use a new solution, where we will sort Famous Movie Characters based on their movie franchise.

So for the purpose of this example, we use the following Model and corresponding ViewModel.

Model:

public class MovieDetail

{

public string Title { get; set; }

public string Name { get; set; }

public string Summary { get; set; }

public string imageUri { get; set; }

}

ViewModel:

public class MovieDetailsViewModel

{

public List<MovieDetail> listMovie;

public MovieDetailsViewModel()

{

listMovie = new List<MovieDetail>();

listMovie.Add(new MovieDetail{Title = "Star Wars", Summary = "BEST MOVIE EVER", Name="Yoda", imageUri = "https://reviewtm.com/wp-content/uploads/2012/10/Star-Wars-Episode-1-The-Phantom-Menace-1999.jpg" });

listMovie.Add(new MovieDetail {Title = "Star Wars", Summary = "BEST MOVIE EVER", Name = "Chewbaka",imageUri = "https://reviewtm.com/wp-content/uploads/2012/10/Star-Wars-Episode-1-The-Phantom-Menace-1999.jpg" });

listMovie.Add(new MovieDetail {Title = "Star Wars", Summary = "BEST MOVIE EVER",Name = "R2D2",imageUri = "https://reviewtm.com/wp-content/uploads/2012/10/Star-Wars-Episode-1-The-Phantom-Menace-1999.jpg" });

listMovie.Add(new MovieDetail{ Title = "Star Wars", Summary = "BEST MOVIE EVER",Name = "C3PO", imageUri = "https://reviewtm.com/wp-content/uploads/2012/10/Star-Wars-Episode-1-The-Phantom-Menace-1999.jpg"});

listMovie.Add(new MovieDetail { Title = "Monsters Inc",Name="Mike", Summary = " BEST MOVIE EVER", imageUri = "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcR5XgUXOE1S---I1wIYoyEvQmYDIHLcb4fRW1fmsS_0w3Y1CqJS" });

listMovie.Add(new MovieDetail { Title = "Batman", Name="Bruce Wayne", Summary = " BEST MOVIE EVER", imageUri = "https://encrypted-tbn3.gstatic.com/images?q=tbn:ANd9GcS-9EWxuTW3BPwMLI9Cv8wl0t2FO92BAdlXUw2UkALbeCxM2s378A" });

listMovie.Add(new MovieDetail { Title = "Avengers", Name="Thor", Summary = " BEST MOVIE EVER", imageUri = "https://encrypted-tbn2.gstatic.com/images?q=tbn:ANd9GcRDCv1_VGA4Gd9BURGyDjPJ3xBHBuer8zTmks_K_a4jWm2o3gVl" });

listMovie.Add(new MovieDetail { Title = "Despicable Me",Name="Minions", Summary = " BEST MOVIE EVER", imageUri = "https://encrypted-tbn2.gstatic.com/images?q=tbn:ANd9GcRHXQ82eKjbiuW_ydn-hcQVCkZDiVhxPe27jwBCs3ewpz9UHm1vOw" });

listMovie.Add(new MovieDetail { Title = "Monsters Inc",Name="Boo", Summary = " BEST MOVIE EVER", imageUri = "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcR5XgUXOE1S---I1wIYoyEvQmYDIHLcb4fRW1fmsS_0w3Y1CqJS" });

listMovie.Add(new MovieDetail { Title = "Batman", Name="Alfred", Summary = " BEST MOVIE EVER", imageUri = "https://encrypted-tbn3.gstatic.com/images?q=tbn:ANd9GcS-9EWxuTW3BPwMLI9Cv8wl0t2FO92BAdlXUw2UkALbeCxM2s378A" });

listMovie.Add(new MovieDetail { Title = "Avengers", Name="Iron Man", Summary = " BEST MOVIE EVER", imageUri = "https://encrypted-tbn2.gstatic.com/images?q=tbn:ANd9GcRDCv1_VGA4Gd9BURGyDjPJ3xBHBuer8zTmks_K_a4jWm2o3gVl" });

listMovie.Add(new MovieDetail { Title = "Avengers", Name = "Hulk", Summary = " BEST MOVIE EVER", imageUri = "https://encrypted-tbn2.gstatic.com/images?q=tbn:ANd9GcRDCv1_VGA4Gd9BURGyDjPJ3xBHBuer8zTmks_K_a4jWm2o3gVl" });

listMovie.Add(new MovieDetail { Title = "Avengers", Name = "Black Widow", Summary = " BEST MOVIE EVER", imageUri = "https://encrypted-tbn2.gstatic.com/images?q=tbn:ANd9GcRDCv1_VGA4Gd9BURGyDjPJ3xBHBuer8zTmks_K_a4jWm2o3gVl" });

listMovie.Add(new MovieDetail { Title = "Avengers", Name = "Hawkeye", Summary = " BEST MOVIE EVER", imageUri = "https://encrypted-tbn2.gstatic.com/images?q=tbn:ANd9GcRDCv1_VGA4Gd9BURGyDjPJ3xBHBuer8zTmks_K_a4jWm2o3gVl" });

listMovie.Add(new MovieDetail { Title = "Avengers", Name = "Captain America", Summary = " BEST MOVIE EVER", imageUri = "https://encrypted-tbn2.gstatic.com/images?q=tbn:ANd9GcRDCv1_VGA4Gd9BURGyDjPJ3xBHBuer8zTmks_K_a4jWm2o3gVl" });

listMovie.Add(new MovieDetail { Title = "Monsters Inc", Name = "Sully", Summary = " BEST MOVIE EVER", imageUri = "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcR5XgUXOE1S---I1wIYoyEvQmYDIHLcb4fRW1fmsS_0w3Y1CqJS" });

listMovie.Add(new MovieDetail { Title = "Batman", Name = "Robin", Summary = " BEST MOVIE EVER", imageUri = "https://encrypted-tbn3.gstatic.com/images?q=tbn:ANd9GcS-9EWxuTW3BPwMLI9Cv8wl0t2FO92BAdlXUw2UkALbeCxM2s378A" });

}

}

Now creating we follow the same steps as before to create add a Long List Control, Set it to Grid mode and set the Data Binding. To make a Custom JumpList we have to carry out the following steps to modify the XAML.

First, we check for the LongList Selector, check IsGroupingEnabled= true.

Second, we set the GroupHeader Style as follows:

<DataTemplate x:Key="groupHeaderTemplate">

<Border Background="Transparent">

<Border Background="Transparent" BorderBrush="Transparent" BorderThickness="1"

Width="400" Height="90"

HorizontalAlignment="Left">

<TextBlock Text="{Binding Title}"

Foreground="{StaticResource PhoneAccentBrush}"

FontSize="28"

Padding="2"

FontFamily="{StaticResource PhoneFontFamilySemiLight}"

HorizontalAlignment="Left"

VerticalAlignment="Center"/>

</Border>

</Border>

</DataTemplate>

The binding for the Header is set to the Title of the Models, as that is the field according to which the binding will be done.

Third, we set the JumpList Style to match the Title. The XAML is as follows:

<phone:JumpListItemBackgroundConverter x:Key="BackgroundConverter"/>

<phone:JumpListItemForegroundConverter x:Key="ForegroundConverter"/>

<Style x:Key="LongListSelectorJumpListStyle" TargetType="phone:LongListSelector">

<Setter Property="LayoutMode" Value="List" />

<Setter Property="Margin" Value="12,12,0,0"/>

<Setter Property="ItemTemplate">

<Setter.Value>

<DataTemplate>

<Border Background="{Binding Converter={StaticResource BackgroundConverter}}"

Width="470"

Height="70"

Margin="6">

<TextBlock Text="{Binding Title}"

Foreground="{Binding Converter={StaticResource ForegroundConverter}}"

FontFamily="{StaticResource PhoneFontFamilySemiBold}"

FontSize="28"

Padding="2"

VerticalAlignment="Bottom"/>

</Border>

</DataTemplate>

</Setter.Value>

</Setter>

</Style>

This sets the Textblock binding to Title again, as that is the field we are sorting according to. Now our XAML setup is complete.

Now to create the custom list in the Code. We create a Class which can be used for any type of custom list creation. You have to just pass the field in the list according to which the Grouping has to be done.

First step, to add the CustomKeyGroup Class. You can copy the following Code:

public class CustomKeyGroup<T> : List<T>

{

public static IEnumerable<MovieDetail> GetMovieList(List<MovieDetail> items)

{

List<MovieDetail> movieList = new List<MovieDetail>();

movieList = items;

return movieList;

}

public static List<Group<MovieDetail>> GetMovieGroups(List<MovieDetail> items)

{

IEnumerable<MovieDetail> movieList = GetMovieList(items);

return GetItemGroups(movieList, c => c.Title);

}

public static List<Group<T>> GetItemGroups<T>(IEnumerable<T> itemList, Func<T, string> getKeyFunc)

{

IEnumerable<Group<T>> groupList = from item in itemList

group item by getKeyFunc(item) into g

orderby g.Key

select new Group<T>(g.Key, g);

return groupList.ToList();

}

public class Group<T> : List<T>

{

public Group(string name, IEnumerable<T> items)

: base(items)

{

this.Title = name;

}

public string Title

{

get;

set;

}

}

}

In the above code, you can set the field you want to sort according to this function:

public static List<Group<MovieDetail>> GetMovieGroups(List<MovieDetail> items)

{

IEnumerable<MovieDetail> movieList = GetMovieList(items);

return GetItemGroups(movieList, c => c.Title);

}

After adding the class, we go to the MainPage C# page, and just assign the Itemsource for our LongListSelector. Here the source list is from my View Model so I will be passing that. You can provide your own list directly as the parameter in the function call. The code is as follows:

MovieDetailsViewModel mvm = new MovieDetailsViewModel();

this.longlist.ItemsSource = CustomKeyGroup<MovieDetail>.GetMovieGroups(mvm.listMovie);

Assign the return type for the CustomKeyGroup as your Model and in the Parameter for GetMovieGroups, add your list.

When you run your solution, you should see the following:

clip_image002clip_image004