I’m rather starting to like doing these look aheads to features coming out in future versions of Xamarin.Forms. It’s really cool tracing through the source code to see how a new feature is being implemented and coming together. And today we’re going to talk about a feature that I keep trying to use, thinking it’s already implemented in Forms… but every time I try, I slap my forehead and remember it’s not there yet … binding a data source to a Picker !!

tl;dr;

All the code from this post can be found on GitHub here.

If you’re only here for the goodness of how to data bind to a Picker … first bind an IList collection to the ItemsSource property. Then bind whatever you want receiving updates to the SelectedItem. Finally, ItemDisplayBinding can receive another binding (from a property within the class’s that make up the IList bound to the ItemsSource), that will determine what gets displayed.

Read on to get the full run down of the new data binding!

New Properties

There are 3 new properties introduced to the Picker as part of the new data binding functionality (more if you count the backing static BindableProperty properties, but we don’t need to directly address those). ItemsSource, SelectedItem, and ItemDisplayBinding.

Let’s break them down one by one.

ItemsSource Property

This is an IList which controls what each element within the Picker contains. The IList is not typed to anything – so you could put a list of whatever type you want into the Picker.

For all the examples that follow, the source of the Picker is the following:

public class Cheese
{
    public string CheeseName { get; set; }
    public string Dairy { get; set; }
    public CheeseTypes Type { get; set; }
    public int Id { get; set; }
 
    static List<Cheese> _allCheeses;
    public static List<Cheese> All
    {
        get
        {
            if (_allCheeses == null)
            {
                _allCheeses = new List<Cheese>
                {
                    new Cheese { CheeseName="Little Boy Blue", Dairy="Hooks", Id=1, Type=CheeseTypes.Blue },
                    new Cheese { CheeseName="10 year", Dairy="Hooks",Id=2, Type=CheeseTypes.Cheddar },
                    new Cheese { CheeseName="Yellow Curds", Dairy="Murphs", Type=CheeseTypes.Curds },
                    new Cheese { CheeseName="St Jenifer", Dairy="Creme de la Coule", Type=CheeseTypes.Farmstead }
                };
            }
 
            return _allCheeses;
        }
    }
}

It’s a class with a bunch of properties (one of which is an enumeration) and then a static property that returns a pre-populated list of data that we’ll use to bind to something. To set the Picker up to data bind, the code would look like the following:

 <Picker ItemsSource="{x:Static local:Cheese.All}" x:Name="thePicker" />
Those options are not much help!

Of course, set the proper xmlns:local up to reference the Cheese class. However, when you run the app, you will see that what is displayed in the Picker looks like what is on the right. The ItemsSource is the means of which to populate the Picker object with data, much in the same way one would do with a ListView. However, that does not mean what one puts in there will get displayed. If you only put a primitive type … an IList of string, an int, etc. that would get displayed exactly. But if you put a class in, whatever the ToString() returns will be displayed.

In order to display something meaningful, we need to make use of the ItemDisplayBinding property.

ItemDisplayBinding Property

The ItemDisplayBinding property is of a BindingBase type, and it allows the Picker to use a property to display text for the options found within the objects it is bound. In other words, ItemDisplayBinding determines what actually gets displayed within the Picker.

The trick here is to realize ItemDisplayBinding is itself a binding (you’d think the name would give it away), so you cannot pass in a string of the property’s name you want to bind to, rather you need to setup another binding. The code to display the CheeseName property in the Picker from the example above would look like the following:

<Picker ItemsSource="{x:Static local:Cheese.All}" 
    ItemDisplayBinding="{Binding CheeseName}" />

Now when the app is run, it displays the following in the picker:

Picker with bindings to an ItemsSource and ItemDisplayBinding

Much better!

Now that we’re able to bind a source to the picker and properly display items, the last piece of the puzzle is to the currently selected item in the picker to a value in a view model. That leads us to SelectedItem.

SelectedItem Property

SelectedItem is a property of type object that changes every time the value within the Picker is updated. By binding SelectedItem to a property in a view model, we can note the choice the user makes from the Picker without any event handling and matching up indexes from the Picker‘s Items property to the SelectedIndex, etc, etc.

The easiest way to see this in action is to define a view model that our view will set to its BindingContext.

public class FavoriteCheese
{
    public Cheese SelectedCheese { get; set; }
}

A very simple view model – only has one property, and that will be the selection from the Picker. Then to hook it up, all one would need to do, other than setting the BindingContext, is the following:

<Picker ItemsSource="{x:Static local:Cheese.All}" 
    ItemDisplayBinding="{Binding CheeseName}" 
    SelectedItem="{Binding SelectedCheese, Mode=TwoWay}" />

Now every time a new selection is made in the Picker, a new value is set in the SelectedCheese property.

And it supports two way binding!

Data binding!

Cool Things

There are a couple of cool things that for some reason or other I wasn’t expecting to happen, but was pleasantly surprised when they did.

  • If the IList that ItemsSource binds to is an ObservableCollection – you can add and change the list of options presented in the Picker at runtime.
  • You can change the SelectedItem in the code behind file and everything works as expected with both the view model and Picker being updated.
  • The SelectedIndexChanged event does still fire regardless of whether data binding is used or not.
  • You cannot use the Items property to add or change elements if data binding is used.

Summary

Finally it’s here! Data binding for the Picker! The usage of it will be familiar if you have used binding with ListViews before. You set the elements to be contained with the ItemsSource. The subtle differences come in with ItemDisplayBinding – that tells the Picker which of the properties in the class’ bound to the ItemsSource to use as the display, otherwise it will use the ToString() of the class. And SelectedItem is the means by which you can find out which item has been selected. This will be available in Xamarin.Forms 2.2.4 … Nice!