Nico's digital footprint

I grew up in the nineties, that makes me awesome by default

LongListSelector with bindable SelectedItem

by Nico

In Windows Phone 8 Microsoft wants us to use the LongListSelector instead of the ListBox. But it seems they forgot about something, the SelectedItem property of the LongListSelector isn’t bindable. There are multiple work-arounds for this like event to command in XAML or setting the viewmodel property from the SelectionChanged event. That last one breaks your entire MVVM setup since the code behind of the view is now directly setting properties on the viewmodel.

Today I once again ran into this problem and decided to extend the LongListSelector to allow SelectedItem binding (note: I haven’t searched for an existing extended LongListSelector so it might as well exist somewhere else, this is just my attempt at it).

Create either a Windows Phone class library or a new class in a WP8 project, I called it ExtendedSelector and have it derive from LongListSelector, you’ll need to add a using statement for the Microsoft.Phone.Controls namespace.

Code Snippet
  1. public class ExtendedSelector : LongListSelector

First we’ll need a dependency property

Code Snippet
  1. public static readonly DependencyProperty SelectedItemProperty =
  2.     DependencyProperty.Register("SelectedItem", typeof (object), typeof (ExtendedSelector), new PropertyMetadata(default(object)));

and the property that is set through the DP

Code Snippet
  1. public new object SelectedItem
  2. {
  3.     get { return GetValue(SelectedItemProperty); }
  4.     set { SetValue(SelectedItemProperty, value); }
  5. }

Notice the “new” keyword on line 1? LongListSelector already has a SelectedItem property of type object, by using the new keyword we make the ExtendedSelector use our version of the property instead of the one from its base class

So now we have a property that can be bound to an object on our viewmodel, all there’s left to do now is set the actual selected item to the property. We do this by handling the SelectionChanged event, the event handler is hooked up in the constructor.

Code Snippet
  1. public ExtendedSelector()
  2. {
  3.     SelectionChanged += (sender, args) =>
  4.     {
  5.             SelectedItem = args.AddedItems[0];
  6.     };
  7. }

And that’s it, we now have a LongListSelector with a bindable SelectedItem property

Multi-select

Let’s take it a step further, we want to enable multi-selection of items in our ExtendedSelector.

Start by adding another dependency property

Code Snippet
  1. public static readonly DependencyProperty SelectionModeProperty =
  2.      DependencyProperty.Register("SelectionMode", typeof (SelectionMode), typeof (ExtendedSelector), new PropertyMetadata(default(SelectionMode)));
  3.  
  4. public SelectionMode SelectionMode
  5. {
  6.      get { return (SelectionMode) GetValue(SelectionModeProperty); }
  7.      set { SetValue(SelectionModeProperty, value); }
  8. }

SelectionMode is an enum containing three types of modes

  • Single
  • Multiple
  • Extended

I only need single and multiple, so I’m not going to do anything with Extended. Change the constructor of the ExtendedSelector to this

Code Snippet
  1. public ExtendedSelector()
  2. {
  3.     SelectionMode = SelectionMode.Single;
  4.  
  5.     SelectionChanged += (sender, args) =>
  6.     {
  7.         if(SelectionMode == SelectionMode.Single)
  8.             SelectedItem = args.AddedItems[0];
  9.         else if (SelectionMode == SelectionMode.Multiple)
  10.         {
  11.             if (SelectedItem == null)
  12.             {
  13.                 SelectedItem = new List<object>();
  14.             }
  15.  
  16.             foreach (var item in args.AddedItems)
  17.             {
  18.                 ((List<object>)SelectedItem).Add(item);                   
  19.             }
  20.  
  21.             foreach (var removedItem in args.RemovedItems)
  22.             {
  23.                 if (((List<object>) SelectedItem).Contains(removedItem))
  24.                 {
  25.                     ((List<object>) SelectedItem).Remove(removedItem);
  26.                 }
  27.             }
  28.         }
  29.     };
  30. }

When the class is instantiated we default the SelectionMode to Single, when the property is set from Xaml the setter fires after the constructor, so this is a safe place to put that. Next in the event handler we check for the SelectionMode, if it’s set to Single, nothing changes. When set to Multiple we check if SelectedItem already contains items, if it does add the newly selected item to the list, if it doesn’t we’ll instantiate SelectedItem first as a List<object>. If there are any deselected items we remove them from the list.

And that’s it. A problem easily solved. I’m just hoping that the product team will actually include this functionality in the next SDK update so this post becomes obsolete.

Conclusion

This post is a quick fix for the LongListSelector so it supports binding to SelectedItem. If you want the complete class, grab it on GitHub

Update

Scott Lovegrove pointed out that the Windows Phone toolkit (http://phone.codeplex.com/ ) has a LongListMultiSelector, allowing for multiple item selection. It still doesn't have a bindable SelectedItem property but it should be pretty easy to make one like I did with the normal LongListSelector it his post.


Tags:

.Net | WP8 | XAML

blog comments powered by Disqus
  Log in

About the author

Hi,

My name is Nico, I’m an MVP Windows Platform Development living in Belgium.
I’m currently employed as a .NET consultant at RealDolmen, one of Belgium’s leading IT single source providers.

I'm also founding member and board member of the Belgian Metro App Developer Network, a user group focussed on Windows 8 and Windows Phone development. If you're in Belgium feel free to drop by if we're doing an event. http://www.madn.be

Since June 2012 I'm a proud member of Microsoft's Extended Experts Team Belgium. And in February 2013 I became a member of DZone's Most Valuable Bloggers family.

In 2013 I became a book author and wrote "Windows 8 app projects, XAML & C# edition".

In 2014 I received the MVP award for the very first time.

I hope to get feedback from my readers either through comments, mail (nico_vermeir@hotmail.com), twitter, facebook, …

 

mvp

 

mvp

 

 

MeetLogo

 

MVBLogo

mybook

 

Month List