views:

27

answers:

1

I have a WPF application with the following KeyBinding on its main window:

<KeyBinding Command="Commands:EditCommands.Undo" Gesture="CTRL+Z" />
<KeyBinding Command="Commands:EditCommands.Redo" Gesture="CTRL+Y" />

This makes the command respond to the shortcut fine. However, in all the places where I have embedded WinForms text boxes or rich text boxes, I've lost the ability to use those shortcuts. If I remove the above bindings, the WinForms shortcuts work fine.

How can I support these shortcuts in both WinForms and WPF? I'd prefer a generic method since this problem is likely to affect many other commands with the same keybindings.

+1  A: 

I'm puzzled why you aren't using the built-in commands:

  • ApplicationCommands.Undo, and
  • ApplicationCommands.Redo

There are several advantages to using these built-in commands:

  1. Their key bindings are automatically for you set based on locale (Ctrl-Z and Ctrl-Y may not be the default undo/redo keys in all locales)
  2. They are honored by TextBox and RichTextBox
  3. They cross the WPF <-> WinForms boundary without any problems
  4. They work with accessibility interfaces
  5. They are invoked by built-in "undo" keys on keyboards that have them

So if possible you should use the built in ApplicationCommands by simply registering CommandBindings for them at the appropriate places in your code.

More information

If you use the built in undo/redo functionality in both WPF and WinForms, it just works. For example, the following creates two RichTextBoxes, one based on WinForms and one on WPF, and both have full undo/redo capabilities:

<UniformGrid Columns="2"
  xmlns:winforms=
    "clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms">

  <WindowsFormsHost >
    <winforms:RichTextBox />
  </WindowsFormsHost>

  <RichTextBox />

</UniformGrid>

Since this works and yours doesn't, try to figure out what is different. You said in your comments you tried removing the custom WPF InputBindings. Have you done the same on the WinForms side? If not, please try it, or if that isn't possible please edit your question to show that code as well.

Note that you can remap ApplicationCommands into your own RoutedCommands: Just add a CommandBinding and in the handler fire your custom RoutedCommand.

Ray Burns
We use a base class for our commands that have the delegates right in the command, so we defined all our commands like that. It was simpler for us to move the Undo/Redo commands there. But regardless, even if I use the built-in command, I still get the same issue. The WPF input bindings block the same bindings from working on WinForms text boxes.
Anthony Brien
Something strange is going on, since this normally works. I've added more information to my answer to help you track it down. It may have something to do with how you're intercepting Ctrl-Y and Ctrl-Z on the WinForms side of the picture.
Ray Burns