1

Version 1 XAML code:

<Button Padding="10" Background="Green" Width="500">
    <StackPanel MouseDown="StackPanel_MouseDown" Background="Gray" Width="500" Height="300">
        <Ellipse MouseDown="Ellipse_MouseDown" Width="100" Height="100" Fill="Red"></Ellipse>
    </StackPanel>
</Button>

Version 1 Code Behind:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }

    private void Ellipse_MouseDown(object sender, MouseButtonEventArgs e)
    {
        MessageBox.Show("This is the Ellipse");
        // Shows this MessageBox.
    }

    private void StackPanel_MouseDown(object sender, MouseButtonEventArgs e)
    {
        MessageBox.Show("This is the StackPanel");
        // Also shows this MessageBox.
    }
}

When I have 2 MouseDown events, one for the Ellipse and one for the StackPanel, whether I use MessageBox or not, it still bubbles up fine after showing the first MessageBox.

However, it stops working if I have the Click event on the Button.

Version 2 XAML Code:

<Button Padding="10" Background="Green" Width="500" Click="Button_Click">
    <StackPanel Background="Gray" Width="500" Height="300">
        <Ellipse MouseDown="Ellipse_MouseDown" Width="100" Height="100" Fill="Red"></Ellipse>
    </StackPanel>
</Button>

Version 2 Code Behind:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }

    private void Ellipse_MouseDown(object sender, MouseButtonEventArgs e)
    {
        MessageBox.Show("This is the Ellipse");
        // Shows this
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        MessageBox.Show("This is the Button");
        // Doesn't get to this point.
    }
}

Now, the weird thing is, if I remove the MessageBox code in the Ellipse handler from Versio n2, and put anything else, it will then bubble up to the Button's handler and show the "This is the Button" message.

What is this weird behavior? Why does Version 1 bubble up and show BOTH MessageBoxes but Version2 only shows one MessageBox and doesn't bubble up unless I remove the MessageBox code?

thatguy
  • 21,059
  • 6
  • 30
  • 40
Sound
  • 113
  • 5

1 Answers1

3

When I have 2 MouseDown events, one for the Ellipse and one for the Stackpanel, whether I use MessageBox or not, it still bubbles up fine after showing the first MessageBox.

This is because you do not set the Handled property to true to stop bubbling further.

private void Ellipse_MouseDown(object sender, MouseButtonEventArgs e)
{
   MessageBox.Show("This is the Ellipse");
   e.Handled = true;
   // Shows this
}

Why does Version 1 bubble up and show BOTH MessageBoxes but Version 2 only shows one MessageBox and doesn't bubble up unless I remove the MessageBox code?

This related answer suggests that showing the message box effectively moves the focus away from the WPF window, which cancels the event routing regardless of setting the Handled property.

The focus change to the message box cancels the mouse down event so it doesn't matter whether it is handled or not.

However, I do not agree with this. From my observations and tests, this issue is only related to modal windows (blocking your UI from interaction). You can create a WPF Window and call ShowDialog, which leads to the same behavior, while showing a window using Show or executing any external application will not stop event routing, even though the focus is moved away from the WPF application. Furthermore, as you show with your code, there can be any number of controls handling MouseDown by showing a modal window as children of a Button which will still work, only to break for the Click event handler of the Button.

In fact, investigating events with Snoop, shows that event handling is the same (left modal windows), the event is not cancelled. The event is always handled by the Button, which is expected as it is implemented this way, but the Click event handler is never called if there was any modal window shown before, although the event is not Handled (false).

Snoop - Events, left modal windows, right non-modal.

Consequently, I would assume that the event handling for Click is somehow broken in scenarios with modal windows. I have not found anything in the documentation about this issue or what is expected, only a similar issue in the MSDN forums.

thatguy
  • 21,059
  • 6
  • 30
  • 40
  • Thank you for the explanation. So, I am assuming that this is a bug internally? – Sound Jun 30 '21 at 08:40
  • @Sound I cannot find any documentation on this behavior. Personally, I would consider this a bug, as this may break anything event related like animations up the visual tree or similar, just by using a modal window, which I would not expect. Nevertheless, this could be another oddity in WPF that is undocumented or even expected, I cannot tell. – thatguy Jun 30 '21 at 08:44