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

时间:2014-09-04 11:19:04

标签: wpf elementhost inputbinding

我有带窗格控件的Windows窗体窗口,其中一个标签托管ElementHost,ContentControl为子元素。此控件具有输入绑定的集合,仅当任何子元素具有输入焦点时才起作用,但如果焦点丢失则它们不再响应。在这种情况下,是否可以在更高级别定义这些输入绑定?

1 个答案:

答案 0 :(得分:2)

一种解决方案可能是将键盘和/或鼠标事件从Win Forms传递(隧道)到WPF主机。我做了以下概念证明。它有效,但有局限性,需要更多的工作。首先,您需要一个派生自 ElementHost 的类。您应该在应用程序中使用它而不是标准的 ElementHost 。这个新的自定义类只有一个额外的方法 ProcessWinFormsKeys ,它将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 实例的表单中,您应该订阅 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的几个问题和互联网上的几十篇文章。