views:

38

answers:

1

I need some assistance in getting WPF KeyBindings working when being called from a WinForm application. I've created what I think is the basic parts to demonstrate the problem. I can provide an sample application if that helps.

The WinForm application starts a form which has a button that calls the WPF

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    Dim view As New WpfPart.MainWindow
    System.Windows.Forms.Integration.ElementHost.EnableModelessKeyboardInterop(view)
    view.ShowDialog()
End Sub

With WPF view creates it's view model and sets up the keybings:

<Window x:Class="WpfPart.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:vm="clr-namespace:WpfPart.ViewModels"
    Title="MainWindow" Height="350" Width="525">
<Window.DataContext>
    <vm:MainWindowViewModel />
</Window.DataContext>
<Window.InputBindings>
    <KeyBinding Key="Escape" Command="{Binding OpenCommand}" Modifiers="Control" />
</Window.InputBindings>
<Grid>

</Grid>

The ViewModel uses a DelagateCommand to hopefully link everything up

using System;
using System.Windows;
using System.Windows.Input;
using WpfPart.Commands;

namespace WpfPart.ViewModels
{
class MainWindowViewModel
{
    private readonly ICommand openCommand;

    public MainWindowViewModel()
    {
        openCommand = new DelegateCommand(Open, CanOpenCommand);
    }

    public ICommand OpenCommand { get { return openCommand; } }
    private bool CanOpenCommand(object state)
    {
        return true;
    }

    private void Open(object state)
    {
        MessageBox.Show("OpenCommand executed.");
    }
}
}

Can anyone see where it is going wrong, the keypress does nothing?!?

A: 

To make the KeyBinding work you need to add a CommandReference to your Window.Resources, and then reference the CommandReference from your KeyBinding (not the Command).

I also used Control-X to avoid opening the Start button in Windows that maps to Control-Escape.

Here is the XAML you can use based on your question:

<Window.Resources>
    <!-- Allows a KeyBinding to be associated with a command defined in the View Model  -->
    <c:CommandReference x:Key="OpenCommandReference" Command="{Binding OpenCommand}" />
</Window.Resources>
<Window.InputBindings>
    <KeyBinding Key="X" Command="{StaticResource OpenCommandReference}" Modifiers="Control" />
</Window.InputBindings>
Zamboni
You don't need that in 4.0, the KeyBinding.Command property is a dependency property so you can bind it. Anyway, if that was the cause of the problem, it would fail at compile time, because you can't bind a non-dependency property
Thomas Levesque
Thanks, you are correct, the code copied from the example did fail to compile in 3.5 sp1. Perhaps the Control-Escape caused the problem.
Zamboni
Yes, the problem was two parts. The (ctrl-Escape) was intercepted by the OS before the application, but the second was human error as when I changed the code the (ctrl-O) it worked fine and when I changed the code back (ctrl-Escape) to reproduce the bug I got the Windows interception (start button menu popup) instead of nothing happening. So I must have mistyped something in code on the first try. Strange that the output window didn't show any errors at runtime...? Dunno, but it works fine now, so this question is answered and closed. Thank you every one for your help.
Cheval