dotnet / maui

.NET MAUI is the .NET Multi-platform App UI, a framework for building native device applications spanning mobile, tablet, and desktop.
https://dot.net/maui
MIT License
22.16k stars 1.74k forks source link

Picker Title displays above the control on Windows #6845

Open WoMart opened 2 years ago

WoMart commented 2 years ago

Description

When running on Windows, the Picker displays the Title property above the control. According to the documentation, and the behaviour on Android, I expect it to be treated as a placeholder when no item is selected.

Documentation snippet: image

Windows: image

Android: image

Steps to Reproduce

  1. Create new MAUI app.
  2. Add a Picker to MainPage.xaml as below (direct copy from Microsoft's sample code)
    <Picker x:Name="picker"
        Title="Select a monkey">
    <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>
  3. Run on Windows Machine

Version with bug

Release Candidate 2 (current)

Last version that worked well

Unknown/Other

Affected platforms

Windows

Affected platform versions

Windows 10 (21H2 | 19044.1645)

Did you find any workaround?

No

Relevant log output

N/A
XamlTest commented 2 years ago

Verified this issue with Visual Studio Enterprise 17.3.0 Preview 1.0 [32427.455.main]. Repro on Windows. Sample Project: MauiApp5.zip

MitchBomcanhao commented 2 years ago

this inconsistency was already present in xamarin.forms - see https://github.com/xamarin/Xamarin.Forms/issues/3646

In xamarin forms you can work around this by creating a custom PickerRenderer for the windows project that does something like this:

        protected override void OnElementChanged(ElementChangedEventArgs<Picker> e)
        {
            base.OnElementChanged(e);

            if (Control != null)
            {
                if (Control != null && !string.IsNullOrWhiteSpace(Element?.Title))
                {
                    Control.HeaderTemplate = new Windows.UI.Xaml.DataTemplate();
                    Control.PlaceholderText = Element.Title;
                }
            }
        }

I've not tried to achieve the same effect in maui yet, but I assume it'll be doable.

MitchBomcanhao commented 2 years ago

my first ever attempt to get a maui handler resulted in being able to get the placeholder text changed to use the picker title, but no luck yet when trying to remove the header from the native view :(

image

mkomel commented 2 years ago

Setting pick.Title = null; after line 15 in @MitchBomcanhao 's code snippet seems to do the trick (to remove the header from the native view).

For completeness, I'm pasting the snippet here again:

#if WINDOWS10_0_19041_0_OR_GREATER
    Microsoft.Maui.Handlers.PickerHandler.Mapper.AppendToMapping(nameof(IPicker.Title), (handler, view) =>
    {
        if (handler.PlatformView is not null && view is Picker pick && !String.IsNullOrWhiteSpace(pick.Title))
        {
            handler.PlatformView.HeaderTemplate = new Microsoft.UI.Xaml.DataTemplate();         
            handler.PlatformView.PlaceholderText = pick.Title;
            pick.Title = null;
         }
    });
#endif
WoMart commented 2 years ago

@mkomel Thanks for the snippet, it works great. I think it's worth noting that the TitleColor property will not be applied to the PlaceholderText, but it can be with the adjustment below.

using WindowsUI = Windows.UI;
using XamlUI = Microsoft.UI.Xaml.Media;

(...)

#if WINDOWS10_0_19041_0_OR_GREATER
  PickerHandler.Mapper.AppendToMapping(nameof(IPicker.Title), (handler, view) => {
      if (handler.PlatformView is not null && view is Picker pick && !string.IsNullOrWhiteSpace(pick.Title)) {
          handler.PlatformView.HeaderTemplate = new Microsoft.UI.Xaml.DataTemplate();
          handler.PlatformView.PlaceholderText = pick.Title;
          pick.Title = null;

          pick.TitleColor.ToRgba(out byte r, out byte g, out byte b, out byte a);
          handler.PlatformView.PlaceholderForeground = new XamlUI.SolidColorBrush(WindowsUI.Color.FromArgb(a, r, g, b));
      }
  });
#endif
mattleibow commented 2 years ago

I see this point of the inconsistency and we probably should add a platform-specific for this? @PureWeen

PureWeen commented 2 years ago

@mattleibow yea, I'm not sure why it'd be useful for us to put that their ourselves. If users want the title their they should just add it themselves :-/ Ideally we could make this default and then the platform specific would be used to restore old behavior, or we possibly switch to a new handler and then users can restore the old handler if they want to.

ghost commented 2 years ago

We've moved this issue to the Backlog milestone. This means that it is not going to be worked on for the coming release. We will reassess the backlog following the current release and consider this item at that time. To learn more about our issue management process and to have better expectation regarding different types of issues you can read our Triage Process.

BigMoonTech commented 2 years ago

I am using Visual Studio Community v17.3.6 and am having this issue as well. Only on Windows, the picker Title and/or placeholder displays above the picker. Would appreciate this coming out of the ol' backlog.

XamlTest commented 1 year ago

Verified this on Visual Studio Enterprise 17.6.0 Preview 5.0. Repro on Windows 11 with below Project: 6845.zip

Different behavior for Windows and Android. Android emulator (13.0-API 33):: image

Windows 11: image

mattleibow commented 1 year ago

Moving this to an enhancement as this is how the OS presents it. However, since this is popular, we can discuss what the options are:

fekberg commented 1 year ago

Still an issue on Android, picker Title is not rendered.

@jfversluis any update on this?

jfversluis commented 1 year ago

@fekberg this issue talks about Windows specifically, could you please find an issue relevant to Android or report one?

Looking at the current state on the main branch (.NET 8) I don't see anything wrong at a first glance on Android.