[英]Is it possible to bind a key to the Click event of a button?
我正在 WPF 上构建一个计算器应用程序,我想将 NumPad 键绑定到它们各自的按钮,因为到目前为止,使用该应用程序的唯一方法是在每个按钮上单击鼠标,这并不理想。
这是第一次使用 WPF 所以我一直在寻找答案但找不到任何有用的东西。
我确实尝试将它添加到我的代码中,但是当我按“A”时它什么也没做。 如果我添加像“Shift”这样的修饰符,它也不起作用。
<Window ...>
<Window.InputBindings>
<KeyBinding Key="A" Command="{Binding Button_Click}"/>
</Window.InputBindings>
...
</Window>
这不是命令的工作方式。 如果您想使用命令来执行自定义行为,我强烈建议您安装CommunityToolkit.Mvvm NuGet package,这将授予您访问RelayCommand
的权限。
通常,对于 MVVM,ViewModel 被设置为视图的 DataContext,但如果您只想使用命令绑定到代码隐藏行为,则不必执行所有这些操作。
在您的 Window 代码隐藏中,添加 RelayCommand 类型的属性并在构造函数中初始化它,将其绑定到 function,如下所示:
public partial class MainWindow : Window
{
public RelayCommand ClickCommand { get; set; }
public MainWindow()
{
InitializeComponent();
ClickCommand = new RelayCommand(ButtonClickAction);
}
private void ButtonClickAction()
{
MessageBox.Show("The Button was clicked!");
}
}
然后在您的 XAML 中,您可以绑定到该命令,只要您绑定到的 DataContext 是Window
class。
这是一个 Button 和 KeyBinding 绑定到相同行为的示例:
<Window ...>
<Window.InputBindings>
<KeyBinding Key="A" Command="{Binding RelativeSource={RelativeSource AncestorType=Window}, Path=ClickCommand}" />
</Window.InputBindings>
<Grid>
<Button Command="{Binding RelativeSource={RelativeSource AncestorType=Window}, Path=ClickCommand}"
Content="Click Me (A)" Width="100" Height="50"/>
</Grid>
</Window>
请注意, RelativeSource
指示绑定,即ClickCommand
RelayCommand 的位置应该在类型为Window
的祖先中找到,因为它是我们定义命令的窗口。
尽管已经给出了解决方案,但我想提出另一个不依赖于 Window 的代码隐藏的实现。
using Simplified;
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Documents;
using System.Windows.Markup;
namespace Helpers
{
/// <summary>Static class with various helper members</summary>
public static partial class WinHelper
{
public static RelayCommand RaiseClickCommand = new RelayCommand(
obj =>
{
switch (obj)
{
case FrameworkElement element:
RoutedEvent? clickEvent = element switch
{
ButtonBase => ButtonBase.ClickEvent,
MenuItem => MenuItem.ClickEvent,
_ => null
};
if (clickEvent is not null)
{
element.RaiseEvent(new RoutedEventArgs(clickEvent));
}
break;
case Hyperlink link:
link.RaiseEvent(new RoutedEventArgs(Hyperlink.ClickEvent));
break;
default: break;
}
},
obj => obj is ButtonBase or MenuItem or Hyperlink
);
}
/// <summary>For ease of use in XAML</summary>
[MarkupExtensionReturnType(typeof(RelayCommand))]
public class RaiseClickExtension : MarkupExtension
{
public override object ProvideValue(IServiceProvider serviceProvider)
{
return WinHelper.RaiseClickCommand;
}
}
}
其使用示例:
<Window.InputBindings>
<KeyBinding Key="A" Command="{helpers:RaiseClick}" CommandParameter="{Binding ElementName=btnA}"/>
<KeyBinding Key="B" Command="{helpers:RaiseClick}" CommandParameter="{Binding ElementName=btnB}"/>
</Window.InputBindings>
<UniformGrid >
<Button x:Name="btnA" Content="Clik Me #A" Click="OnClickMeA"/>
<Button x:Name="btnB" Content="Clik Me #B" Click="OnClickMeB"/>
<x:Code>
<![CDATA[
private void OnClickMeA(object sender, RoutedEventArgs e)
{
MessageBox.Show("Click A");
}
private void OnClickMeB(object sender, RoutedEventArgs e)
{
MessageBox.Show("Click B");
}
]]>
</x:Code>
</UniformGrid>
此解决方案可用于任何类型的按钮(Button、CheckBox 等)、MenuItem 和 Hyperlink。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.