microsoft / microsoft-ui-xaml

WinUI: a modern UI framework with a rich set of controls and styles to build dynamic and high-performing Windows applications.
MIT License
6.38k stars 683 forks source link

"PointerExited" event when ComboBox clicked to open Drop Down #8649

Open AndreasErikCoder opened 1 year ago

AndreasErikCoder commented 1 year ago

Describe the bug

To set the context: We have a WinUI 3 based Crayons application for kids to select the colour and draw in Windows application. The control employed for selection is a WinUI ComboBox control.

We have modified the ComboBox template to suit our Crayons application design--- the Drop Down has been moved to the bottom of ComboBox control when "IsEditable" is FALSE. However, when it is clicked to open the Drop Down, we can notice that a PointerExited is fired.

This is noticeable because we have set PointerCursor of ComboBox as HAND and it turns to ARROW when clicked on the control.

We want to retain the mouse cursor as HAND.

Steps to reproduce the bug

CrayonsTestApp_v2.zip

  1. Load the sample application provided.
  2. Move cursor above ComboBox -> Notice cursor is HAND
  3. Click the ComboBox -> Notice cursor becomes ARROW

Expected behavior

Cursor should remain HAND.

Screenshots

No response

NuGet package version

WinUI 3 - Windows App SDK 1.3.2: 1.3.230602002

Windows version

Windows 10 (21H2): Build 19044

Additional context

Please acknowledge if this is an issue with the WinUI control. It would be great if any workarounds could be suggested.

tom-huntington commented 1 week ago

PointerExited fires in Parent when child ComboBox opens

The pointer is always over the Grid but PointerExited fires

<Window ....>
    <Grid PointerExited="Grid_PointerExited" Background="DarkGreen">
            <ComboBox x:Name="MyComboBox" VerticalAlignment="Center" HorizontalAlignment="Center">
                <ComboBoxItem Content="1" />
                <ComboBoxItem Content="2" />
            </ComboBox>
    </Grid>
</Window>

The best work around is an early return in your PointerExited handler

void Grid_PointerExited(IInspectable const&, PointerRoutedEventArgs const&)
{
    if (MyComboBox().IsDropDownOpen()) return;
}

An maybe handle ComboBox.DropDownClosed

tom-huntington commented 1 week ago

It's because ComboBox is implemented with a Popup https://github.com/microsoft/microsoft-ui-xaml/blob/63671e055eadfd74806f9800382b8bd6c9999b4a/controls/dev/ComboBox/ComboBox_themeresources.xaml#L589

<Grid PointerExited="Grid_PointerExited" Background="DarkGreen" Loaded="Grid_Loaded">
    <Popup x:Name="MyPopup" Height="100" Width="100" >
        <Grid Background="Cyan" Width="100" Height="100"/>
    </Popup>
</Grid>