Bassie
Bassie

Reputation: 10390

Simple keyboard shortcut to activate button click event

I have a very simple WPF application which has a button:

<Button x:Name="buttonNextImage" Content="&gt;" Margin="0,0,0.4,-0.2" 
        Click="buttonNextImage_Click" HorizontalAlignment="Right" Width="25"
        Background="Transparent"
        BorderThickness="0">
</Button>

All I want to do is allow the user to activate this button's click event by pressing the right arrow key on their keybaord while the application window is in focus.

I checked this answer, but I don't have a label to add an underscore to - the only text I want the button to display is a > - surely it is possible to achieve this without resorting to adding a label.

I also tried the answer here but I just get this annoying error in my xaml saying MyCommand does not exist, even though I delcared it in the code-behind.

Any guidance on this is much appreciated..

Upvotes: 0

Views: 2577

Answers (3)

JohnyL
JohnyL

Reputation: 7142

Alternatively to KeyDown event (my previous suggestion), you could use ready baked-in ComponentCommands.MoveRight command. You can press > key or button. Here's the usage (note: there's even no need in InputBindings!):

XAML

<Window x:Class="WPFApp.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Window.CommandBindings>
        <CommandBinding Command="ComponentCommands.MoveRight" Executed="OnMoveRight"/>
    </Window.CommandBindings>
    <StackPanel>
        <Button Content=">" Command="ComponentCommands.MoveRight"/>
    </StackPanel>
</Window>

C#

private void OnMoveRight(object sender, ExecutedRoutedEventArgs e)
{
    // Do something with image
    MessageBox.Show("Either button or '>' key was pressed");
}

Upvotes: 1

Bassie
Bassie

Reputation: 10390

I went with JohnyL's solution in the comments like this:

<Window KeyDown="OnKeyDownHandler">

code behind

private void OnKeyDownHandler(object sender, KeyEventArgs e)
{
    switch (e.Key)
    {
        case Key.Right:
            NextImage();
            break;
        case Key.Left:
            PreviousImage();
            break;
        default:
            break;
    }
}

Nice and simple, but it is a shame WPF doesn't just have an easy way of doing this built in to its controls.

Upvotes: 0

wp78de
wp78de

Reputation: 18950

You can implement <CommandBindings> and <InputBindings>:

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApplication1"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Window.InputBindings>
        <KeyBinding Key="Right"
                    Command="{Binding MessageCommand}"
                    CommandParameter="You pressed 'Right Arrow'"/>
    </Window.InputBindings>
    <Grid>
        <Button Margin="45" Command="{Binding MessageCommand}">Click Me</Button>

    </Grid>
</Window>

Code behind:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace WpfApplication1
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            DataContext = new MyDataContext();
        }

        public class MessageCommand : ICommand    
        {
            public void Execute(object parameter)
            {
                string msg;

                if (parameter == null)
                    msg = "Button Clicked!";
                else
                    msg = parameter.ToString();

                MessageBox.Show(msg);
            }

            public bool CanExecute(object parameter)
            {
                return true;
            }

            public event EventHandler CanExecuteChanged;
        }

        public class MyDataContext
        {
            ICommand _messageCommand = new MessageCommand();

            public ICommand MessageCommand
            {
                get { return _messageCommand; }
            }
        }
    }
}

Here is the list of Keys: https://msdn.microsoft.com/en-us/library/system.windows.input.key(v=vs.100).aspx

Upvotes: 1

Related Questions