1

First: I know that there are literally thousands of answers like: "Add a handler to Keyboard.KeyDownEvent and have fun!". But in my situation this does not work.

I have a custom control CustomControl which derives from Canvas but has no Children. Instead it draws its "children" directly to the DrawingContext in the OnRender. My Control is HitTestVisible, it is tab stop but is not focusable. It is often reused and sometimes in a ScrollViewer.

This CustomControl has a custom implementation for selecting something like text, and should copy that selected text to the ClipBoard on Ctrl+C.

To do this, I added a handler in the constructor:

public CustomControl()
{
    //// ... other stuff
    AddHandler(Keyboard.KeyDownEvent, (KeyEventHandler)CopyMarkedNucleotidesToClipboard);
}

And here is the Problem: When my control is inside a ScrollViewer, and I hit Ctrl+C, the KeyDownEvent is raised on the ScrollViewer and bubbles up to the window, and therefore never reaches my Control.

What can I do inside my CustomControl to capture every Ctrl+C in the window where it resides?

PS: I already set IsTabStop="False" and Focusable="False". But then the next sibling of the ScrollViewer would raise the event which would still bubble up to the window. And I don't want to go through all controls which are higher in the visual tree and set IsTabStop="False" and Focusable="False" which would be wrong...

I already found this article http://blogs.msdn.com/b/toub/archive/2006/05/03/589423.aspx but I think, that there must be a more wpf-like way!

Rico-E
  • 1,806
  • 2
  • 28
  • 47
  • Is there a "KeyPreview" event in the form?? If yes, try add a listener to that event and handle keydown event in the form.. – User2012384 Jul 24 '15 at 08:08
  • *What can I do inside my CustomControl to capture every Ctrl+C in my application* - that suggest what you catch it on application level and inform your control. You probably have just one window (but calling it application), so forwarding calls (commands?) to control via event or somehow else should be the way. – Sinatr Jul 24 '15 at 08:08
  • @User2012384: The Preview event just starts at the window and stops at the `ScrollViewer`. So it still doesn't reach my control. – Rico-E Jul 24 '15 at 08:12
  • @Sinatr: I can't (don't want to) go through all the places where `CustomControl` is used, add a handler on the window level and forward it to my control. I would prefer a solution in the `CustomControl`. So that I may change the key combination to Ctrl+U in the future, without visiting all windows again... – Rico-E Jul 24 '15 at 08:15
  • You can make your control to do that automatically. E.g. in the `Load` event it can find his parent window and subscribe to parent window event (maybe directly to key down, not sure, all your windows can implement some interface with event which will be used by control to subscribe). – Sinatr Jul 24 '15 at 08:17

1 Answers1

1

The suggestion of Sinatr was correct! Thanks!

The solution is to find the parent window in the load and subsribe to his KeyDownEvent.

public CustonControl()
{
    Loaded += HookToCtrlC;
}

private void HookToCtrlC(object sender, EventArgs e)
{
    var parentWindow = Window.GetWindow(this);
    parentWindow.KeyDown += CopySelectedTextToClipboard;
}

private void CopyMarkedNucleotidesToClipboard(object sender, KeyEventArgs e)
{
    Clipboard.SetText("Hello World!");
}
Rico-E
  • 1,806
  • 2
  • 28
  • 47