Skip to content
This repository was archived by the owner on May 1, 2024. It is now read-only.

[Bug] Programmatically setting focus to TimePicker or DatePicker should not open popup on UWP (note edit for iOS 14 handling!) #12174

Open
johnshardman opened this issue Sep 18, 2020 · 7 comments

Comments

@johnshardman
Copy link

Description

A change was introduced recently (see links below) that has resulted in programmatically setting the focus to a TimePicker or DatePicker on UWP automatically opening the picker's popup. Whilst that might be consistent with what happens on Android and iOS, it is not what a native Windows user would expect. Either the change should be unwound, or an override provided so that opening the popup becomes optional. Adding that option would mean that developers do not have to write custom renderers to remove the automatic opening (or write a custome renderer to add the behavior back in if it were removed completely).

#10909
#10916

Steps to Reproduce

  1. Create a TimePicker or DatePicker
  2. Call Focus() on the TimePicker or DatePicker
  3. Build and run on UWP

Expected Behavior

The TimePicker or DatePicker should receive focus, but not open the popup (until either the user hits the space button, or taps on the picker)

Actual Behavior

The TimePicker or DatePicker opens automatically

Basic Information

  • Version with issue: 4.8 (I believe also in 4.7 but haven't tested)
  • Last known good version: 4.5
@johnshardman johnshardman added s/unverified New report that has yet to be verified t/bug 🐛 labels Sep 18, 2020
@rmarinho rmarinho added the p/UWP label Sep 22, 2020
@rmarinho
Copy link
Member

Hi @johnshardman do you know any example on the Windows OS we can try the native behavior ?

@rmarinho rmarinho added 4.7.0 regression on 4.7.0 i/regression a/datepicker a/timepicker and removed s/unverified New report that has yet to be verified labels Sep 22, 2020
@johnshardman
Copy link
Author

By definition, the native behavior is what happens when Windows.UI.Xaml.Controls.TimePicker and Windows.UI.Xaml.Controls.DatePicker are allowed to do their own thing, rather than overriding behavior and additionally forcing a flyout to appear, which is what the code added in XF 4.7 (see below) is doing.

	internal override void OnElementFocusChangeRequested(object sender, VisualElement.FocusRequestArgs args)
	{
		base.OnElementFocusChangeRequested(sender, args);

		// Show a picker fly out on focus to match iOS and Android behavior
		var flyout = new TimePickerFlyout { Placement = FlyoutPlacementMode.Bottom, Time = Control.Time };
		flyout.TimePicked += (p, e) => Control.Time = p.Time;
		if (!Element.IsVisible)
			flyout.Placement = FlyoutPlacementMode.Full;
		flyout.ShowAt(Control);
	}

The comment in that code says it all really - it's been added "to match iOS and Android behavior", rather than to let the native controls do what they would otherwise do.

I'm sure that one of the Windows team at Microsoft, or somebody who worked with Windows previously such as Charles Petzold could confirm expected behavior.

@bmacombe
Copy link
Contributor

There was discussion at one point of adding a ShowDialog to allow better control.

#5159 (comment)

Maybe late for XF 5, but maybe Maui?

Here is the original issue that started this change. #7992

@johnshardman
Copy link
Author

For those people who want Android/iOS behavior on Windows, finer control could be provided by having an override of Focus, passing a flag that indicates whether native behavior is wanted (default), or Android/iOS behavior is wanted (non-default).

@johnshardman
Copy link
Author

johnshardman commented Sep 30, 2020

Having just updated a test device to iOS 14, I propose that Picker, DatePicker and TimePicker handling be re-visited across platforms, to allow the developer to specify not just what happens on each platform when each type of picker receives focus (programmatically or as a result of user action) in terms of does the picker just receive focus or does it open/flyout, but also allow the developer to specify the type of picker display where different options are available (as per iOS 14 using the PreferredDatePickerStyle property of UIDatePicker). With iOS 14, this is no longer just a UWP issue, as iOS 14 allows for pickers to be inline in a form rather than appear as a separate set of wheels in a popup.

For more info about the iOS 14 change, see #12258 and https://developer.apple.com/design/human-interface-guidelines/ios/controls/pickers/

@johnshardman johnshardman changed the title [Bug] Programmatically setting focus to TimePicker or DatePicker should not open popup on UWP [Bug] Programmatically setting focus to TimePicker or DatePicker should not open popup on UWP (note edit for iOS 14 handling!) Sep 30, 2020
@AntonTereshko1995
Copy link

I had this issue too on UWP platform with Picker. I could not open Picker when I called Picker.Focus(); in Xamarin.Forms.
I fixed this issue with custom renderer in UWP project.

`
[assembly: ExportRenderer(typeof(Picker), typeof(AllPickerRenderer))]
namespace SkillReporter.UWP.Renderers
{
public class AllPickerRenderer : PickerRenderer
{
private bool isOpened;

    protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        base.OnElementPropertyChanged(sender, e);

        if (e.PropertyName == VisualElement.IsFocusedProperty.PropertyName)
        {
            if (Element.IsFocused)
            {
                if (!isOpened)
                {
                    Control.IsDropDownOpen = true;
                    this.isOpened = true;
                }
                else
                {
                    this.isOpened = false;
                }
            }
        }
    }
}

}`

@dan-meier
Copy link

I agree with @bmacombe that a ShowDialog method would be a better, more "neutral" approach, avoiding the issue with different UWP behavior that @johnshardman notes.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

5 participants