Skip to content

Instantly share code, notes, and snippets.

@markjulmar
Last active December 7, 2015 20:31
Show Gist options
  • Save markjulmar/d91a00e03fc255141058 to your computer and use it in GitHub Desktop.
Save markjulmar/d91a00e03fc255141058 to your computer and use it in GitHub Desktop.
PickerCollection
using System;
using Xamarin.Forms;
using System.Collections;
using System.Diagnostics;
namespace MusicSearch.Infrastructure
{
public class PickerBindBehavior : Behavior<Picker>
{
Picker associatedPicker;
bool updatingValue;
#region ItemsProperty
public static BindableProperty ItemsProperty =
BindableProperty.Create<PickerBindBehavior,IEnumerable>(
be => be.Items,
null,
propertyChanged: ItemsChanged);
public IEnumerable Items
{
get { return (IEnumerable) base.GetValue(ItemsProperty); }
set { base.SetValue(ItemsProperty, value); }
}
static void ItemsChanged(BindableObject bindableObject, object oldValue, object newValue)
{
var behavior = bindableObject as PickerBindBehavior;
behavior.OnItemsChanged((IEnumerable)oldValue, (IEnumerable)newValue);
}
#endregion
#region SelectedItemProperty
public static BindableProperty SelectedItemProperty =
BindableProperty.Create<PickerBindBehavior, object>(
be => be.SelectedItem,
null,
BindingMode.TwoWay,
propertyChanged: SelectedItemChanged);
public object SelectedItem
{
get { return base.GetValue(SelectedItemProperty); }
set { base.SetValue(SelectedItemProperty, value); }
}
static void SelectedItemChanged(BindableObject bindableObject, object oldValue, object newValue)
{
var behavior = bindableObject as PickerBindBehavior;
behavior.OnSelectedItemChanged(oldValue, newValue);
}
#endregion
protected override void OnAttachedTo(Picker bindable)
{
if (associatedPicker != null)
{
associatedPicker.SelectedIndexChanged -= OnSelectedIndexChanged;
}
associatedPicker = bindable;
associatedPicker.SelectedIndexChanged += OnSelectedIndexChanged;
OnItemsChanged(null, Items);
OnSelectedItemChanged(null, SelectedItem);
}
protected override void OnDetachingFrom(Picker bindable)
{
Debug.Assert(associatedPicker == bindable);
bindable.SelectedIndexChanged -= OnSelectedIndexChanged;
}
void OnItemsChanged(IEnumerable oldValue, IEnumerable newValue)
{
if (associatedPicker == null)
return;
associatedPicker.Items.Clear ();
if (newValue == null)
return;
foreach (var item in newValue) {
associatedPicker.Items.Add ((item ?? "").ToString());
}
}
void OnSelectedItemChanged(object oldValue, object newValue)
{
if (associatedPicker == null || updatingValue)
return;
updatingValue = true;
try
{
if (newValue == null)
{
associatedPicker.SelectedIndex = -1;
}
var items = Items;
if (items == null)
return;
int index = -1;
IList itemList = items as IList;
if (itemList != null)
{
index = itemList.IndexOf(newValue);
}
else
{
foreach (object testValue in items)
{
index++;
if (Equals(testValue, newValue))
break;
}
}
associatedPicker.SelectedIndex = index;
}
finally
{
updatingValue = false;
}
}
void OnSelectedIndexChanged(object sender, EventArgs e)
{
if (associatedPicker == null || updatingValue)
return;
var items = Items;
if (items == null)
return;
int selectedIndex = associatedPicker.SelectedIndex;
if (selectedIndex == -1)
{
SelectedItem = null;
return;
}
object value = null;
IList itemList = items as IList;
if (itemList != null)
{
value = itemList[selectedIndex];
}
else
{
int index = 0;
foreach (object testValue in items)
{
if (index == selectedIndex)
{
value = testValue;
break;
}
index++;
}
}
SelectedItem = value;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment