If anyone wonders how to make a Bindable Picker, here's the code:
`
public class BindablePicker : Picker
{
#region Fields
//Bindable property for the items source
public static readonly BindableProperty ItemsSourceProperty =
BindableProperty.Create<BindablePicker, IEnumerable>(p => p.ItemsSource, null, propertyChanged: OnItemsSourcePropertyChanged);
//Bindable property for the selected item
public static readonly BindableProperty SelectedItemProperty =
BindableProperty.Create<BindablePicker, object>(p => p.SelectedItem, null, BindingMode.TwoWay, propertyChanged: OnSelectedItemPropertyChanged);
#endregion
#region Properties
/// <summary>
/// Gets or sets the items source.
/// </summary>
/// <value>
/// The items source.
/// </value>
public IEnumerable ItemsSource
{
get { return (IEnumerable)GetValue(ItemsSourceProperty); }
set { SetValue(ItemsSourceProperty, value); }
}
/// <summary>
/// Gets or sets the selected item.
/// </summary>
/// <value>
/// The selected item.
/// </value>
public object SelectedItem
{
get { return GetValue(SelectedItemProperty); }
set { SetValue(SelectedItemProperty, value); }
}
#endregion
#region Methods
/// <summary>
/// Called when [items source property changed].
/// </summary>
/// <param name="bindable">The bindable.</param>
/// <param name="value">The value.</param>
/// <param name="newValue">The new value.</param>
private static void OnItemsSourcePropertyChanged(BindableObject bindable, IEnumerable value, IEnumerable newValue)
{
var picker = (BindablePicker)bindable;
var notifyCollection = newValue as INotifyCollectionChanged;
if (notifyCollection != null)
{
notifyCollection.CollectionChanged += (sender, args) =>
{
if (args.NewItems != null)
{
foreach (var newItem in args.NewItems)
{
picker.Items.Add((newItem ?? "").ToString());
}
}
if (args.OldItems != null)
{
foreach (var oldItem in args.OldItems)
{
picker.Items.Remove((oldItem ?? "").ToString());
}
}
};
}
if (newValue == null)
return;
picker.Items.Clear();
foreach (var item in newValue)
picker.Items.Add((item ?? "").ToString());
}
/// <summary>
/// Called when [selected item property changed].
/// </summary>
/// <param name="bindable">The bindable.</param>
/// <param name="value">The value.</param>
/// <param name="newValue">The new value.</param>
private static void OnSelectedItemPropertyChanged(BindableObject bindable, object value, object newValue)
{
var picker = (BindablePicker)bindable;
if (picker.ItemsSource != null)
picker.SelectedIndex = picker.ItemsSource.IndexOf(picker.SelectedItem);
}
#endregion
}
`
Usage is pretty straight forward..:
<local:BindablePicker ItemsSource="{Binding Cats}" SelectedItem="{Binding SelectedCat}"/>
It would've been nice that the Xamarin.Forms.Picker already had this functionality, maybe we'll see it in a next update...
Any questions, comments, or contributions are welcome