locked
KeyEventArgs Event Chain. Altered Event data when another event with the same shared class is raised (no snapshot?) RRS feed

  • Pregunta

  • Hello!

    I am overriding an PreviewKeyDown Event and listening for Keystrokes with an Modifier-Key. When i hit the desired key i call a method which evaluates the input and shows a dialog (which requires a user action).
    The Problem here is that, whenever another (input) event is raised (in my example a MouseEventArgs), the modifier key from the first event in the KeyboardDevice class gets altered (Even though they don't even share that class in the EventArgs?). When i hold the modifier key and click on the button on the dialog, i receive the modifier key on the code below.

    I didn't figure out why that would happen at all. According to a book (https://www.oreilly.com/library/view/programming-wpf-2nd/9780596510374/ch04.html ---- Chapter 4-13) there should be some sort of snapshot from the time the event has been raised.
    Some Events share the event data among each other (https://docs.microsoft.com/en-us/dotnet/api/system.windows.input.keyeventargs?view=netcore-3.1), so i guess that is also the case here.

    What is the expected behaviour regarding modifiers on the first event being raised?

    Here i narrowed down the problem, it is still the same event being raised, not altered by me:

    Tested with .NET Framework 4.7.1, 4.8 and .NET Core:
            protected override void OnPreviewKeyDown(KeyEventArgs e)
            {
                base.OnPreviewKeyDown(e);
                if (e.Key == Key.S && e.KeyboardDevice.Modifiers == ModifierKeys.Control)
                {
                    Debug.WriteLine($@"Debugging Event. Before Validator-Chain. Hash: {e.GetHashCode()}, Key-Modifier: {e.KeyboardDevice.Modifiers}"); //Debugging Event. Before Validator-Chain. Hash: 64833183, Key-Modifier: Control      
                    MessageBox.Show("test", "", MessageBoxButton.YesNo);
                    Debug.WriteLine($@"Debugging Event. After Validator-Chain. Hash: {e.GetHashCode()}, Key-Modifier: {e.KeyboardDevice.Modifiers}"); //Debugging Event. After Validator-Chain. Hash: 64833183, Key-Modifier: None       
                }
            }
    
    

    The problem with this beviour (in my case) is that i alter a textbox, save with the Gesture (also happens with KeyBinding) Ctrl+S and the modifier gets removed during validation and the framework further down the chain seems to see the keystroke "Ctrl+S" as a pure "S" keystroke and therefor alters and overwrites the content of a textbox.

    If you need further information, please let me know as this is my first issue...

    Edit: I think this is a .NET Topic (as this also happens with VB.NET), but i got refered here first..


    • Editado Erythana miércoles, 19 de agosto de 2020 7:54
    • Cambiado CoolDadTx miércoles, 19 de agosto de 2020 14:23 Winforms related
    miércoles, 19 de agosto de 2020 7:52

Todas las respuestas

  • If it is suitable to cancel further processing of keyboard message, then you can execute ‘e.Handled = true’ after MessageBox.Show.

    But if you do not use PreviewKeydown and instead use the corresponding <KeyBinding> and <CommandBinding>, then it seems to work as expected (i.e. ‘S’ is not inserted into textbox after closing the message box).

    miércoles, 19 de agosto de 2020 10:17
  • Hi Erythana,
    First, you need to set KeyEventArgs.Handled to true to cancel further processing  as Viorel said. 
    And if you mark PreviewKeyDown as handled, the corresponding KeyDown event will not fire at all.  This works because the two events share the same instance of a KeyEventArgs object. So when PreviewKeyDown marks the event as handled, KeyDown also treats the event as handled.
    Second, as offical document said that "You should not put any logic in the PreviewKeyDown event handler, other than to set the IsInputKey property. Instead, you should put your logic in the KeyDown event handler." 
    So you can use KeyDown event to handle it.
    Here is a simple code example:

    private void textBox1_KeyDown(object sender, KeyEventArgs e)
    {
        if (e.KeyCode == Keys.S && e.Modifiers == Keys.Control)
        {
            MessageBox.Show("test", "", MessageBoxButtons.YesNo);
        }
    }

    Best Regards,
    Daniel Zhang


    "Windows Forms General" forum will be migrating to a new home on Microsoft Q&A (Preview)!
    We invite you to post new questions in the "Windows Forms General" forum’s new home on Microsoft Q&A (Preview)!
    For more information, please refer to the sticky post.

    jueves, 20 de agosto de 2020 7:08
  • Hi Erythana,
    Has your problem been solved? If it is resolved, we suggest that you mark it as the answer. So it can help other people who have the same problem find a solution quickly.
    Best Regards,
    Daniel Zhang


    "Windows Forms General" forum will be migrating to a new home on Microsoft Q&A (Preview)!
    We invite you to post new questions in the "Windows Forms General" forum’s new home on Microsoft Q&A (Preview)!
    For more information, please refer to the sticky post.

    viernes, 28 de agosto de 2020 1:41