'How can we handle the done button click event for a Xamarin Forms Picker?

I want to fire a click event on the Done button on a Picker in Xamarin Forms. I found some people having custom render for entry, but how can we implement the done button in a Picker on Xamarin forms iOS?



Solution 1:[1]

You can use a custom renderer to achieve this. Looking at the source code for the Picker on iOS, you can see that the 'Done' button is added to a UIToolbar. You can get a reference to the button and then handle its 'Clicked' event:

public class MyPickerRenderer : PickerRenderer
{
    protected override void OnElementChanged(ElementChangedEventArgs<Picker> e)
    {
        base.OnElementChanged(e);

        if(e.OldElement != null)
        {
            var toolbar = (UIToolbar)Control.InputAccessoryView;
            var doneBtn = toolbar.Items[1];

            doneBtn.Clicked -= DoneBtn_Clicked;
        }

        if(e.NewElement != null)
        {
            var toolbar = (UIToolbar)Control.InputAccessoryView;
            var doneBtn = toolbar.Items[1];

            doneBtn.Clicked += DoneBtn_Clicked;
        }
    }

    void DoneBtn_Clicked(object sender, EventArgs e)
    {
        Console.WriteLine("Clicked!!!!");
    }
}

Solution 2:[2]

A workaround I made without custom render is that first you need to change the behavior that the selected item works on iOS, with this code:

<ContentPage xmlns:ios="clr-namespace:Xamarin.Forms.PlatformConfiguration.iOSSpecific;assembly=Xamarin.Forms.Core">
    <StackLayout Margin="20">
        <Picker x:Name="picker"
               Title="Select a monkey"
               ios:Picker.UpdateMode="WhenFinished"
               TitleColor="Red">
        <Picker.ItemsSource>
        <x:Array Type="{x:Type x:String}">
           <x:String>Baboon</x:String>
           <x:String>Capuchin Monkey</x:String>
           <x:String>Blue Monkey</x:String>
           <x:String>Squirrel Monkey</x:String>
           <x:String>Golden Lion Tamarin</x:String>
           <x:String>Howler Monkey</x:String>
           <x:String>Japanese Macaque</x:String>
        </x:Array>
  </Picker.ItemsSource>
</Picker>
    </StackLayout>
</ContentPage>

and after that try to listen to the Unfocused and SelectedIndexChanged events handlers

void picker_Unfocused(System.Object sender, Xamarin.Forms.FocusEventArgs e)
{
       //I want to reset the selected index every time the picker is closed.                  
       picker.SelectedIndex = -1;
}

void picker_SelectedIndexChanged(System.Object sender, System.EventArgs e)
{
    //Just in case the unfocused is fired first i make a validation to call an action
    if (picker.SelectedIndex >= 0){
     App.Current.MainPage.DisplayAlert("Selected monkey: ", picker.SelectedItem.ToString(), "Aceptar");
    }
}

And you will be able to see that the Alert on Android will display when the object in the entry is tapped and on iOS will be displayed when the item is selected AND when the user makes click on the Done button

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 jimmgarr
Solution 2 LAlvarenga