Skip to content

Instantly share code, notes, and snippets.

@Pravin-Divraniya
Created October 25, 2017 08:17
Show Gist options
  • Select an option

  • Save Pravin-Divraniya/db48f5273c1c9c7bc9bd029b2be64fcb to your computer and use it in GitHub Desktop.

Select an option

Save Pravin-Divraniya/db48f5273c1c9c7bc9bd029b2be64fcb to your computer and use it in GitHub Desktop.
This custom picker resolves one issue (issue :- User can't be able to handle done button in default iOS Picker) in Xamarin forms.
namespace CustomControl
{
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
public BindablePicker() {
if (Device.OS == TargetPlatform.iOS)
{
this.Unfocused += OnUnfocused;
}
else {
this.SelectedIndexChanged += OnSelectedIndexChanged;
}
}
void OnUnfocused(object sender, FocusEventArgs args) {
OnSelectedIndexChanged(sender,args);
}
void OnSelectedIndexChanged(object sender,EventArgs args) {
var picker = (BindablePicker)sender;
if (picker != null && picker.ItemsSource != null)
picker.SelectedItem = picker.Items[picker.SelectedIndex];
}
#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
}
public static class EnumerableExtensions
{
/// <summary>
/// Returns the index of the specified object in the collection.
/// </summary>
/// <param name="self">The self.</param>
/// <param name="obj">The object.</param>
/// <returns>If found returns index otherwise -1</returns>
public static int IndexOf(this IEnumerable self, object obj)
{
int index = -1;
var enumerator = self.GetEnumerator();
enumerator.Reset();
int i = 0;
while (enumerator.MoveNext())
{
if (enumerator.Current == obj)
{
index = i;
break;
}
i++;
}
return index;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment