AvaloniaUI / Avalonia

Develop Desktop, Embedded, Mobile and WebAssembly apps with C# and XAML. The most popular .NET UI client technology
https://avaloniaui.net
MIT License
26.1k stars 2.26k forks source link

Popups do not forward events to their parent windows #9515

Open TomEdwardsEnscape opened 2 years ago

TomEdwardsEnscape commented 2 years ago

Describe the bug The PopupRoot class is explicitly designed to pass RoutedEvents to its parent window.

It does not do so, because its parent is not a window but a Popup object. Popup.InteractiveParent returns the value of Popup.VisualParent, which is always null.

To Reproduce Create a window with this XAML:

<Window xmlns="https://github.com/avaloniaui" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" x:Class="AvaloniaApplication.MainWindow">
    <Grid>
        <Button HorizontalAlignment="Center" VerticalAlignment="Center" Content="Left-click me">
            <Button.ContextMenu>
                <ContextMenu>
                    <MenuItem Header="Click me" Click="MenuItem_Click"/>
                </ContextMenu>
            </Button.ContextMenu>
        </Button>
    </Grid>
</Window>

And this C#:

using Avalonia.Controls;
using Avalonia.Interactivity;
using System.Diagnostics;

namespace AvaloniaApplication
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            AddHandler(MenuItem.ClickEvent, OnMenuItemClick);
            AddHandler(Button.ClickEvent, OnButtonClick);
        }

        private void OnButtonClick(object? sender, RoutedEventArgs e)
        {
            Debug.WriteLine("Button click detected from Window");
            ((Button)e.Source!).Content = "Right-click me";
        }

        private void OnMenuItemClick(object? sender, RoutedEventArgs e) => Debug.WriteLine("Menu click detected from Window");

        private void MenuItem_Click(object? sender, RoutedEventArgs e) => Debug.WriteLine("Menu click detected on MenuItem");
    }
}

Follow the on-screen instructions and you will see this debug output:

Button click detected from Window
Menu click detected on MenuItem

The menu click is not detected on the window.

Expected behavior Events should be forwarded from the context menu to its parent window. In the case of the window above, this debug output should be produced after clicking on the menu item:

Menu click detected from Window

Desktop (please complete the following information):

grokys commented 2 years ago

This is an issue with ContextMenus and Flyouts specifically, because they create a Popup that isn't hosted in the visual tree.

I think the solution to this should be simple: if the Popup has no visual parent, use the logical parent as the interactive parent, i.e. override IInteractive.InteractiveParent in Popup.