Question

The problem:

  1. KeyUp is handled by the grid in main window (Grid_KeyUp)
  2. Main window shows a child window (e.g. MessageBox.Show(...))
  3. User presses [Return] (Keys.Return) to close the MessageBox
  4. Main window actually GETS the KeyUp event from that keypress in MessageBox

I have a very simple isolated sample that shows the problem I am having. Just create an empty WPF project and use this XAML:

<Grid KeyUp="Grid_KeyUp">
    <Button Click="Button_Click"></Button>
</Grid>

And the code-behind:

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

    private void Grid_KeyUp(object sender, KeyEventArgs e)
    {
        Console.WriteLine("KEYUP: " + e.Key);
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        MessageBox.Show(this, "TEST");
    }
}

If you click the button and press [Return] to close the MessageBox the output window will print:

KEYUP: Return

Weird facts:

  1. I get the same behaviour when pressing [Escape] (KEYUP: Escape gets printed), but when I press [Space] the console does not print out anything!
  2. e.Source and e.OriginalSource point to the button in the main window (which is, obviously, wrong).
  3. If you put a breakpoint right after MessageBox.Show(...) the event does not get handled by out KeyUp handler (i.e. the output is empty).

Could anyone explain to me what is happening?

PS Target framework is: .NET 4 Client

Was it helpful?

Solution

Clearly what is happening is that when you press the enter or escape, the message box closes and before you lift up the button the MainWindow gets focus and catches the KeyPress aswell .

The reason why this is not happening with the space bar is that pressing spacebar pushes the button down, but does not release it until you release the spacebar yourself. This means that the spacebar is released before the button is "unpressed" and therefore the MessageBox only closes once the spacebar is released, so the MainWindow does not catch the button press.

You can test this by holding the spacebar in. You will see that the button is held down but is not pressed until you release it.

You could prolly create a flag that goes off after the MessageBox close. Check if it's the first KeyPress (and maybe check that it happened less than 10 miliseconds after the close) and then just ignore it.

I know, its ugly, but I don't think there's much else you can do (if I'm right)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top