繁体   English   中英

是否可以将按键绑定到按钮的 Click 事件?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM