如何在父控件上获得键击以到达承载实际绑定但未聚焦的子控件

问题描述

如果我需要澄清或发布更多代码,请告诉我!

我可以找到很多关于如何将击键从子元素传递到父元素的资源,而不是方法

我解释一下我的用例:

我有一个父级 Window(我们称之为 wndSession),其中有几个可聚焦的控件和一个 ContentControl,它使用 { 分配其内容UserControl) {1}} 个绑定。

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" /> 可能分配了不同的 UserControl,只要焦点在 KeyBingind 上,一切正常。

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 将不再对 KeyBinding 做出反应。这不是一个真正好的用户体验......

我需要的是一种方法

首先,我想到了一些类似“冒泡”到 UserControl 的子控件的击键,尤其是 wndSession 中的 UserControl,如果 {{ 1}} 尚未解决 KeyBinding。

但如前所述,这会导致很多问题。因此,为了避免冲突(哪个控件现在可以使用它的绑定等),我认为需要的是将击键传递给指定的目标,在我的情况下,如果 {{1 }} 无法处理密钥,因为未指定绑定。

简而言之:Contentcontrol 作为路由器将所有未知按键(未由 wndSession 注册)传递到网关/代理 (wndSession/ wndSession)

那么将只有一条沿着树向下的路径,冲突的风险很小。目前我无法从父级模拟目标控件上的击键,因此它的 KeyBinding 可以触发。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)