Forum Xamarin.Forms

Picker Selection Event

Hi,

I have a problem with xamarin form picker.
I need to have an event when the "done" (ios) or "ok" (android) button was clicked. Cause i want to open a popup when user select an item.
I only see a SelectedIndexChanged how is fire each time user stop scrolling (on iOS, can't see on android).

Anyone know how I can put an event when picker is closed ?

Posts

  • CraigDunnCraigDunn USXamarin Team Xamurai

    Maybe some combination of checking the old and new values along with the Unfocused event? Sorry I haven't tested that, just an idea.

  • JimmyAumardJimmyAumard USMember

    Yes with the Unfocused event I can do this thanks @CraigDunn‌ ! But when I set picker value the entry was not changing with the new selected value... it's normal ?

    CodesPicker.SelectedIndexChanged += (object sender, EventArgs e) => 
    {
        CodesPicker.Unfocus();
        CodesPicker.SelectedIndex = 0;//On the screen picker stay at the old value
    };
    
  • TeoTeo DKMember ✭✭

    @CraigDunn‌ It looks like the Android Picker fires its SelectedIndexChanged event on the press of the ok button, while iOS fires its event whenever the selection changes in the picker. Is this intended behavior? It would be nice if both platforms sent the event only after clicking done/ok.>

    +1 to this.

  • AndyHopperAndyHopper USMember ✭✭

    @CraigDunn‌ It looks like the Android Picker fires its SelectedIndexChanged event on the press of the ok button, while iOS fires its event whenever the selection changes in the picker. Is this intended behavior? It would be nice if both platforms sent the event only after clicking done/ok.

    Yes, please. I have an app that is fetching from a Web service when an item is selected from a Picker. It works exactly as intended on Android - it only fetches when the user indicates they have made their selection by clicking the "Done" button (incidentally, this is the behavior one observes on XF's spiritual ancestor WPF). On iOS, the app is fetching like mad as the user scrolls around. If this isn't the best way to know when a selection should be considered "complete," please provide some official guidance.

  • TeoTeo DKMember ✭✭

    @deckertron9000 I managed to work around this by not doing anything when the SelectedIndexChanged event is triggered, but instead doing the work when the Unfocused event is triggered.

    Managed to make that work with Android by using some nasty #if IOS and #if ANDROID directives to segment my code. Not ideal, but it works.

    What I am most annoyed about is that I have absolutely no access to the Done button click events. Generally speaking, if it appears on the screen, I should be able to control it. Even when implementing a custom picker renderer, unless I want to implement from scratch, I have to subclass their PickerRenderer. And that class only gives access to the UITextField on iOS, and keeps the UIPickerView private., thus making me unable to change anything.

  • deckertron9000deckertron9000 USUniversity ✭✭✭

    @ConstantinGherghescu‌ a workaround is never ideal :) glad you got it working though! I'm using a PCL for my core code so compiler directives aren't a possibility for me right now. I agree that it's ridiculous for a developer not to be able to handle a click event of an on-screen button. I had tried subclassing awhile back and met with the same issue you mention, no access to the UIPickerView.

  • ScottSmith.8058ScottSmith.8058 USMember, University

    @Teo is your project a Xamarin.Forms project? I do not see an Unfocused event exposed for a Picker in Forms. I only see the Focused event?

  • deckertron9000deckertron9000 USUniversity ✭✭✭

    @ScottSmith.8058
    Unfocused is an Event exposed by VisualElement in Xamarin.Forms.

  • ScottSmith.8058ScottSmith.8058 USMember, University

    @deckertron9000 Thanks. For some reason intellisence was not showing it. A restart of VS solved that.

  • LuisMarquesLuisMarques GBMember, University ✭✭

    Xamarin - any idea when this picker behaviour will be made consistent across platforms? iOS is firing this event when I stop scrolling as opposed to when I click "done" which is the more correct behaviour, which I have seen works perfect in Android. I have yet to test it on Windows Phone.

  • RogerSchmidlinRogerSchmidlin CHUniversity ✭✭✭

    This doesn't work if you want to check, if the cancel button has been clicked. I would expect Android to fire a unfocused event, but it doesn't :( Very inconsistent to iOS!

  • BradSmelster.5783BradSmelster.5783 USMember ✭✭

    Hi..
    What's the solution... no click event etc

  • BradSmelster.5783BradSmelster.5783 USMember ✭✭

    Sorry.. still don't understand how you handle the 'Done'. thx

  • deckertron9000deckertron9000 USUniversity ✭✭✭

    With the device specific you don't need to handle the "done" button specifically. It just delays the IndexChanged from firing until after you tap "done".

  • BradSmelster.5783BradSmelster.5783 USMember ✭✭

    thx again!

  • EeedgarEeedgar USMember ✭✭
    edited June 2017

    @deckertron9000 thanks so much for popping back and posting after so long on this - works perfectly, got me out of a pickle and opened my mind to platform specifics. Happy Friday!

    I still needed to wrap the line of code in a dependency service though to stop this tripping up Android and UWP. When called directly in the PCL, this caused the view in non-iOS to return a blank view without the DS...

  • RamyAssafRamyAssaf USMember ✭✭

    @deckertron9000 said:
    @JElster.5783 This has finally been addressed with platform specifics in Forms 2.3.4
    To fix the iOS behavior to match other platforms use the following method:

    var picker = new Picker();
    picker.On<iOS>().SetUpdateMode(UpdateMode.WhenFinished);
    

    This thread can finally be laid to rest.

    That's the solution, thanks a lot

  • @deckertron9000 said:
    @JElster.5783 This has finally been addressed with platform specifics in Forms 2.3.4
    To fix the iOS behavior to match other platforms use the following method:

    var picker = new Picker();
    picker.On<iOS>().SetUpdateMode(UpdateMode.WhenFinished);
    

    This thread can finally be laid to rest.

    Im trying to get this to work for DatePicker but it doesn't appear to work.

  • TamasMatraiTamasMatrai HUUniversity ✭✭

    @deckertron9000 said:
    @JElster.5783 This has finally been addressed with platform specifics in Forms 2.3.4
    To fix the iOS behavior to match other platforms use the following method:

    var picker = new Picker();
    picker.On<iOS>().SetUpdateMode(UpdateMode.WhenFinished);
    

    This thread can finally be laid to rest.

    No.

    It is not supported by DatePicker!

  • TamasMatraiTamasMatrai HUUniversity ✭✭
    edited January 2018

    @DReinhold said:
    A bit late on the ball perhaps but I just had this problem myself. If your Picker is not a standard picker but a control inheriting from Picker (in my case a BindablePicker) you can just do something like this:

    public BindablePicker()
    {
      if (Device.OS == TargetPlatform.iOS)
      {
          this.Unfocused += OnUnfocused;
      }
      else
      {
          this.SelectedIndexChanged += OnSelectedIndexChanged;
      }
    }
    
    private void OnUnfocused(object sender, FocusEventArgs e)
    {
      OnSelectedIndexChanged(sender, e);
    }
    

    That way, Android will use the "Standard" way of handling the index change and iOS will wait until the "Done"-button is tapped.

    I don't think it would be an ideal solution: if you unfocus (~close) picker on IOS by tapping on the screen outside the picker, Unfocus is triggered. It should be a 'cancel feature', but in your solution it equals with Done.

  • DavidClarkeDavidClarke NZBeta, University ✭✭

    Pieter Nijs has a useful post that addresses this issue in XAML rather than having to write code.

  • Ian123Ian123 GBMember ✭✭
    edited May 2018

    This works on the simulator but not on my device - because I had the old version installed on my device. :)

  • JayzonJayzon Member

    For my android project, I came across this discussion while looking for a Picker clicked event solution. The SelectedIndexChanged event would work the first time a user clicked an Index, but if the same Index was clicked again it would not fire the SelectedIndexChanged event (which makes sense). The workaround for my project was to set the SelectedIndex to -1 when the SelectedIndexChanged is fired.

    Example :

    pHelp.SelectedIndexChanged += (object sender, EventArgs e) =>
                {
                    try
                    {
                        string selection = pHelp.SelectedItem.ToString();
    
                        if (selection == "EXIT APP")
                        {
                            OnAlertYesNoClicked();
    
                            //Allows this SelectedIndexChanged event to be a Clicked event
                            pHelp.SelectedIndex = -1;
                        }
                    }
    
                    catch
                    {
                        //to do
                    }
    
                };
    
                async void OnAlertYesNoClicked()
                {   
                   var answer = await DisplayAlert("Exit Application", "Are you sure?", "Yes", "No");
                   if(answer) { System.Diagnostics.Process.GetCurrentProcess().Kill(); } 
                }
    

    I hope this helps someone

Sign In or Register to comment.