我有带窗格控件的Windows窗体窗口,其中一个标签托管ElementHost,ContentControl为子元素。此控件具有输入绑定的集合,仅当任何子元素具有输入焦点时才起作用,但如果焦点丢失则它们不再响应。在这种情况下,是否可以在更高级别定义这些输入绑定?
答案 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的几个问题和互联网上的几十篇文章。