Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the best way to handle the same shortcut in WPF and WinForms controls?

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.

like image 510
Anthony Brien Avatar asked Nov 05 '22 12:11

Anthony Brien


1 Answers

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.

like image 93
Ray Burns Avatar answered Nov 15 '22 05:11

Ray Burns