Skip to content

Instantly share code, notes, and snippets.

@hhyyg
Last active February 10, 2017 05:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hhyyg/a83d6e9574389c373edbddfb97a1d950 to your computer and use it in GitHub Desktop.
Save hhyyg/a83d6e9574389c373edbddfb97a1d950 to your computer and use it in GitHub Desktop.
MyBindableCustomPicker / Xamarin.Forms
using System;
using System.Collections;
using System.Collections.Specialized;
using Xamarin.Forms;
namespace Miso.SearchForms.Controls
{
/// <summary>
/// Bindable Custom Picker
///
/// Xamarin.Forms 2.3.4がでれば、そっちを使った方が良い
/// </summary>
public class CustomPicker : Picker
{
public CustomPicker()
{
//TODO: OnPropertyChangedの"SelectedIndex"でいけるかどうか?
this.SelectedIndexChanged += CustomPicker_SelectedIndexChanged;
}
public static readonly BindableProperty ItemsSourceProperty =
BindableProperty.Create(nameof(ItemsSource), typeof(IList), typeof(CustomPicker), default(IList),
propertyChanged: OnItemsSourceChanged);
public static readonly BindableProperty SelectedItemProperty =
BindableProperty.Create(nameof(SelectedItem), typeof(object), typeof(CustomPicker), null, BindingMode.TwoWay,
propertyChanged: OnSelectedItemChanged);
public IList ItemsSource
{
get { return (IList)GetValue(ItemsSourceProperty); }
set { SetValue(ItemsSourceProperty, value); }
}
public object SelectedItem
{
get { return GetValue(SelectedItemProperty); }
set { SetValue(SelectedItemProperty, value); }
}
private void CustomPicker_SelectedIndexChanged(object sender, EventArgs e)
{
var itemsSource = this.ItemsSource;
if (itemsSource == null || itemsSource.Count == 0)
return;
this.SelectedItem = (itemsSource.Count >= this.SelectedIndex + 1) ? itemsSource[this.SelectedIndex] : null;
}
private static void OnItemsSourceChanged(BindableObject bindable, object oldValue, object newValue)
{
OnItemsSourceChanged(((CustomPicker)bindable), (IList)oldValue, (IList)newValue);
}
private static void OnItemsSourceChanged(CustomPicker picker, IList oldValue, IList newValue)
{
picker.Items.Clear();
if (newValue == null)
return;
NotifyCollectionChangedEventHandler handler = (sender, e) => CollectionChanged(picker, e);
var oldObservable = oldValue as INotifyCollectionChanged;
if (oldObservable != null)
{
oldObservable.CollectionChanged -= handler;
}
var newObservable = newValue as INotifyCollectionChanged;
if (newObservable != null)
{
newObservable.CollectionChanged += handler;
}
foreach (var item in newValue)
{
picker.Items.Add(item.ToString());
}
}
static void CollectionChanged(CustomPicker picker, NotifyCollectionChangedEventArgs e)
{
switch (e.Action)
{
case NotifyCollectionChangedAction.Add:
AddItems(picker, e);
break;
case NotifyCollectionChangedAction.Remove:
throw new NotImplementedException();
default: //Move, Replace, Reset
picker.Items.Clear();
picker.SelectedItem = null;
break;
}
}
private static void OnSelectedItemChanged(BindableObject bindable, object oldValue, object newValue)
{
OnSelectedItemChanged((CustomPicker)bindable, oldValue, newValue);
}
private static void OnSelectedItemChanged(CustomPicker picker, object oldValue, object newValue)
{
if (picker.ItemsSource == null)
{
throw new Exception("ItemSource is null");
}
if (newValue == null)
{
picker.SelectedIndex = -1;
return;
}
picker.SelectedIndex = picker.ItemsSource.IndexOf(newValue);
return;
}
private static void AddItems(CustomPicker picker, NotifyCollectionChangedEventArgs e)
{
int index = e.NewStartingIndex < 0 ? picker.Items.Count : e.NewStartingIndex;
foreach (object newItem in e.NewItems)
picker.Items.Insert(index++, newItem.ToString());
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment