如果我需要澄清或发布更多代码,请告诉我!
我可以找到很多关于如何将击键从子元素传递到父元素的资源,但不是这样。
我解释我的用例:
我有一个带有几个可聚焦控件的父级Window
(我们称之为它wndSession
)和一个使用绑定分配ContentControl
其内容(a )的控件。UserControl
DataTemplate
<Window.Resources>
<DataTemplate DataType="{x:Type vm:vmLearnModule1}">
<local:viewLearnModule1 />
</DataTemplate>
<DataTemplate DataType="{x:Type vm:vmLearnModule2}">
<local:viewLearnModule2 />
</DataTemplate>
<DataTemplate DataType="{x:Type vm:vmLearnModule3}">
<local:viewLearnModule3 />
</DataTemplate>
<DataTemplate DataType="{x:Type vm:vmLearnResults}">
<local:viewLearnResults />
</DataTemplate>
</Window.Resources>
和:
<ContentControl Content = "{Binding learningViewModel}"
Name = "contentControl"
Grid.Row = "1"
Grid.Column = "1"
Height = "300"
Margin = "20, 0, 0, 0" />
现在每个人都UserControl
可能分配了不同KeyBingind
的 s,只要重点放在UserControl
所有作品上就可以了。
UserControl 上的绑定示例:
<UserControl.InputBindings>
<KeyBinding Key="F1" Command="{Binding cmdResultNotKnown}"/>
<KeyBinding Key="F2" Command="{Binding cmdResultAlmostKnown}"/>
<KeyBinding Key="F3" Command="{Binding cmdResultKnown}"/>
</UserControl.InputBindings>
我的命令都是这样定义的:
private ICommand _cmdTest;
/// <summary>
/// Test
/// </summary>
public ICommand cmdTest => this._cmdTest ??= new RelayCommand(param => this.doTest(), param => this.canTest);
private bool canTest => true;
private void doTest()
{
// Some code here
}
现在到这个问题:
如果我单击父窗口上的任何可聚焦控件wndSession
,则UserControl
或其当前聚焦的子控件将失去焦点,并且父窗口 ( wndSession
) 的控件将获得焦点(好吧,到目前为止我希望如此)。
但正因为如此,除非我单击第一个的任何控件,否则UserControl
不会再对 s 做出反应。这不是一个非常好的用户体验......KeyBinding
UserControl
我需要的是一种方法:
首先,我想到了类似“冒泡”对子控件的击键wndSession
,尤其是UserControl
在尚未解决 KeyBindingContentcontrol
的事件中。wndSession
但正如所说,这会导致许多问题。因此,为了避免冲突(哪个控件现在可以使用它的绑定等),我认为需要将击键传递给指定的目标,在我的情况下,如果wndSession
无法处理,它将是 ContentControl 中的 UserControl没有指定绑定的键。
简而言之:wndSession
作为路由器运行,将所有未知的击键(未由 a 注册)KeyBinding
传递给网关/代理(ContentControl
/ UserControl
)
那么就只有一条沿着树向下的路径,几乎没有冲突的风险。目前我无法从父级模拟目标控件上的击键,因此它的 KeyBinding 可以触发。