gpt4 book ai didi

wpf - InputBindings 仅在聚焦时才起作用

转载 作者:行者123 更新时间:2023-12-02 00:59:17 24 4
gpt4 key购买 nike

我设计了一个可重用的用户控件。它包含 UserControl.InputBindings。它非常简单,因为它只包含一个标签和一个按钮(以及新属性等)

当我在窗口中使用该控件时,它运行良好。但键绑定(bind)仅在聚焦时才起作用。当一个控件绑定(bind)到 alt+f8 时,此快捷键仅在获得焦点时才起作用。当另一个具有自己的绑定(bind)的焦点被聚焦时,那个可以工作,但 alt+f8 不再有效。当没有一个控件获得焦点时,什么都不起作用。

如何实现我的用户控件定义窗口范围的键绑定(bind)?

特别是遵循 MVVM 设计模式(使用 Caliburn.Micro),但感谢任何帮助。

<小时/>

用户控件的XAML:

<UserControl x:Class="MyApp.UI.Controls.FunctionButton"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:MyApp.UI.Controls"
xmlns:cm="http://www.caliburnproject.org"
x:Name="Root"
Focusable="True"
mc:Ignorable="d"
d:DesignHeight="60" d:DesignWidth="120">
<UserControl.Resources>
...
</UserControl.Resources>
<UserControl.InputBindings>
<KeyBinding Key="{Binding ElementName=Root, Path=FunctionKey}" Modifiers="{Binding ElementName=Root, Path=KeyModifiers}" Command="{Binding ElementName=Root, Path=ExecuteCommand}" />
</UserControl.InputBindings>
<DockPanel LastChildFill="True">
<TextBlock DockPanel.Dock="Top" Text="{Binding ElementName=Root, Path=HotkeyText}" />
<Button DockPanel.Dock="Bottom" Content="{Binding ElementName=Root, Path=Caption}" cm:Message.Attach="[Event Click] = [Action ExecuteButtonCommand($executionContext)]" cm:Action.TargetWithoutContext="{Binding ElementName=Root}" />
</DockPanel>
</UserControl>

使用示例:

    <Grid>
<c:FunctionButton Width="75" Height="75" Margin="10,10,0,0" VerticalAlignment="Top" HorizontalAlignment="Left" FunctionKey="F1" ShiftModifier="True" cm:Message.Attach="[Event Execute] = [Action Button1Execute]" />
<c:FunctionButton Width="75" Height="75" Margin="10,90,0,0" VerticalAlignment="Top" HorizontalAlignment="Left" FunctionKey="F2" ShiftModifier="True" cm:Message.Attach="[Event Execute] = [Action Button2Execute]" />
</Grid>

正如所说,每个按钮在鼠标单击时都可以工作(执行被触发),并且当聚焦时,我可以使用空格来激活按钮,并且聚焦按钮的输入绑定(bind)可以工作,但不能使用未聚焦的按钮。

最佳答案

由于其工作方式,不会对未聚焦的控件执行InputBindings - 在可视化树中从聚焦元素到可视化树的根(窗口)搜索输入绑定(bind)的处理程序。当控件未获得焦点时,它不会成为该搜索路径的一部分。

正如 @Wayne 所提到的,最好的方法是将输入绑定(bind)移动到父窗口。但有时这是不可能的(例如,当窗口的 xaml 文件中未定义 UserControl 时)。

我的建议是使用附加行为将这些输入绑定(bind)从 UserControl 移动到窗口。使用附加行为执行此操作还有一个好处是能够在任何 FrameworkElement 上工作,而不仅仅是您的 UserControl。所以基本上你会得到这样的东西:

public class InputBindingBehavior
{
public static bool GetPropagateInputBindingsToWindow(FrameworkElement obj)
{
return (bool)obj.GetValue(PropagateInputBindingsToWindowProperty);
}

public static void SetPropagateInputBindingsToWindow(FrameworkElement obj, bool value)
{
obj.SetValue(PropagateInputBindingsToWindowProperty, value);
}

public static readonly DependencyProperty PropagateInputBindingsToWindowProperty =
DependencyProperty.RegisterAttached("PropagateInputBindingsToWindow", typeof(bool), typeof(InputBindingBehavior),
new PropertyMetadata(false, OnPropagateInputBindingsToWindowChanged));

private static void OnPropagateInputBindingsToWindowChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
((FrameworkElement)d).Loaded += frameworkElement_Loaded;
}

private static void frameworkElement_Loaded(object sender, RoutedEventArgs e)
{
var frameworkElement = (FrameworkElement)sender;
frameworkElement.Loaded -= frameworkElement_Loaded;

var window = Window.GetWindow(frameworkElement);
if (window == null)
{
return;
}

// Move input bindings from the FrameworkElement to the window.
for (int i = frameworkElement.InputBindings.Count - 1; i >= 0; i--)
{
var inputBinding = (InputBinding)frameworkElement.InputBindings[i];
window.InputBindings.Add(inputBinding);
frameworkElement.InputBindings.Remove(inputBinding);
}
}
}

用法:

<c:FunctionButton Content="Click Me" local:InputBindingBehavior.PropagateInputBindingsToWindow="True">
<c:FunctionButton.InputBindings>
<KeyBinding Key="F1" Modifiers="Shift" Command="{Binding FirstCommand}" />
<KeyBinding Key="F2" Modifiers="Shift" Command="{Binding SecondCommand}" />
</c:FunctionButton.InputBindings>
</c:FunctionButton>

关于wpf - InputBindings 仅在聚焦时才起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23316274/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com