1
votes

I need to handle "KeyDown" event during the drag and drop action.

The goal is to show some notification or change cursor when user is holding 'alt' and dragging an object.

But I have noticed that KeyDown is not working, only ESC button is responding somehow!

I tried already to run it with the next DLL import code:

   [DllImport("user32.dll")]
private static extern short GetKeyState(Keys key);

This can show whether button was pressed, but I really searching for the press even! Any tip how to handle keyboard down event when dragging an object?

1
I get KeyDown events on the form that's doing the mouse capture, though it doesn't have a control with focus. What have you tried? - arx
all possible controls was signed with "keydown" handler. - Ievgen
I'd run spy++ and see where the keyboard messages are going. They definitely get generated. - arx

1 Answers

2
votes

You can try to use:

bool isKeyPressed = Keyboard.IsKeyDown(Key.LeftAlt);

And put it into apropriate event that fits your needs, like DragEnter, DragOver or use a timer and check the state of the key at a constant rate.

If you use a Timer that fires event often enough (like each 100ms) it should appear to react instantly. You can use an additional flag to handle each key press and release once (and NOT each time the timer fires its event).

UPDATE

I've implemented this just to test it and it seems to work correctly even if a user is dragging something (I've tested this for dragging a text).

It's for a simple case, when you want to detect key down and key up events for one specific key (left ALT), but it can be quite easily modified to monitor as many keys as you want.

First, add two fields to the class of the Window you want to detect the key down and key up in:

DispatcherTimer timer = new DispatcherTimer();
bool keyPressed = false;

DispatcherTimer is used here, so the event raised by timer is executed in the context of window's UI thread.

Next, add a method Window_Loaded to the window's Loaded event.

Then, you can implement the method you've just added as Loaded event handler and initialize the timer there:

 private void Window_Loaded(object sender, RoutedEventArgs e)
 {
     timer.Tick += new EventHandler(timer_Tick);
     //timer will raise an event checking key state each 100ms
     timer.Interval = TimeSpan.FromMilliseconds(100);
     timer.Start();
 }

Finally, you should add implementation of timer_Tick method that is checking state of the key that you want to monitor:

void timer_Tick(object sender, EventArgs e)
    {
        if (Keyboard.IsKeyDown(Key.LeftAlt))
        {
            //checking flag to handle each key press only once
            if (!keyPressed)
            {
                keyPressed = true;

                //TODO: write your key down handling code here
                //i.e.: sampleRichTextBox.AppendText("Left Alt is down;\t");
            }
        }
        else
        {
            //checking flag to handle each key release only once
            if (keyPressed)
            {
                keyPressed = false;

                //TODO: write your key up handling code here
                //i.e.: sampleRichTextBox.AppendText("Left Alt is up;\t");
            }
        }
    }

If you need any more information about this solution, let me know.