当WPF内容托管在WinForms中时,如何使用命令的输入绑定



我有一个带有选项卡控件的Windows窗体窗口,它的一个选项卡宿主ElementHost,ContentControl作为子元素。此控件具有输入绑定的集合,这些绑定仅在任何子元素具有输入焦点时才起作用,但如果焦点丢失,它们将不再作出反应。在这种情况下,是否可以在更高级别上定义这些输入绑定?

一种解决方案可能是将键盘和/或鼠标事件从Win Forms传递(隧道)到WPF主机。我做了以下概念验证。它有效,但有局限性,需要做更多的工作。首先,您需要一个从ElementHost派生的类。您应该在应用程序中使用它,而不是标准的ElementHost。这个新的自定义类将只有一个额外的方法ProcessWinFormsKey,它将把WinForms特定的键映射到WPF使用的键。然后它会找到一个合适的输入绑定并执行它

    public class CustomElementHost : ElementHost
    {
        public void ProcessWinFormsKeys(Keys keys, Keys modifiers)
        {
            var key = KeyInterop.KeyFromVirtualKey((int)keys);
            var modifier = System.Windows.Input.ModifierKeys.None;
            if ((modifiers & Keys.Control) != 0)
                modifier |= System.Windows.Input.ModifierKeys.Control;
            if ((modifiers & Keys.Shift) != 0)
                modifier |= System.Windows.Input.ModifierKeys.Shift;
            if ((modifiers & Keys.Alt) != 0)
                modifier |= System.Windows.Input.ModifierKeys.Alt;
            foreach (InputBinding inputBinding in Child.InputBindings)
            {
                var keyGesture = inputBinding.Gesture as KeyGesture;
                if (keyGesture == null) 
                    continue;
                if(keyGesture.Key == key && keyGesture.Modifiers == modifier)
                    if(inputBinding.Command.CanExecute(inputBinding.CommandParameter))
                        inputBinding.Command.Execute(inputBinding.CommandParameter);
            }
        }
    }

然后,在包含CustomElementHost实例的Form中,您应该订阅KeyDown事件,并在处理程序中调用ProcessWinFormsKeys方法:

    public Form()
    {
        InitializeComponent();
        KeyPreview = true;
        KeyDown += Form_KeyDown;
        ...
    }
    void Form_KeyDown(object sender, KeyEventArgs e)
    {
       elementHost.ProcessWinFormsKeys(e.KeyCode, e.Modifiers);
    }

另一种解决方案可能是使用全局热键。它需要使用user32.dll中的RegisterHotKey函数。但是,我不确定它是否能与ElementHost一起使用。如果你想尝试一下,有一些关于stackoverflow的问题和互联网上的几十篇文章。

最新更新