programing tip

WPF의 키보드 단축키

itbloger 2020. 7. 12. 10:12
반응형

WPF의 키보드 단축키


_대신 에 사용 하는 방법을 알고 &있지만 모든 Ctrl+ 유형 단축키를보고 있습니다.

Ctrl+ Z실행 취소, Ctrl+ S저장 등

WPF 응용 프로그램에서이를 구현하기위한 '표준'방법이 있습니까? 아니면 자신만의 롤을 사용하여 명령 / 제어에 연결합니까?


표준 방법은 명령을 만든 다음 바로 가기 키를 입력 제스처로 추가하는 것입니다.

이를 통해 바로 가기 키가 컨트롤에 연결되어 있지 않아도 작동 할 수 있습니다. 메뉴 항목은 키보드 동작을 이해하므로 해당 명령을 메뉴 항목에 연결하면 메뉴 항목 텍스트에 바로 가기 키가 자동으로 표시됩니다.

  1. 명령을 보유 할 정적 속성을 작성하십시오 (명령에 대해 작성하는 정적 클래스의 특성으로 권장되지만 간단한 예에서는 window.cs의 정적 속성 만 사용).

    public static RoutedCommand MyCommand = new RoutedCommand();
    
  2. 메소드를 호출해야하는 단축키를 추가하십시오.

    MyCommand.InputGestures.Add(new KeyGesture(Key.S, ModifierKeys.Control));
    
  3. 실행시 호출 할 메소드를 가리키는 명령 바인딩을 작성하십시오. 이것들이 작동해야 할 UI 요소 (예 : 창)와 메소드의 명령 바인딩에 이것을 넣으십시오 :

    <Window.CommandBindings>
        <CommandBinding Command="{x:Static local:MyWindow.MyCommand}" Executed="MyCommandExecuted"/>
    </Window.CommandBindings>
    
    private void MyCommandExecuted(object sender, ExecutedRoutedEventArgs e) { ... }
    

나는 이것이 WPF의 키 바인딩과 관련하여 정확히 찾고있는 것으로 나타났습니다.

<Window.InputBindings>
        <KeyBinding Modifiers="Control"
                    Key="N"
                    Command="{Binding CreateCustomerCommand}" />
</Window.InputBindings>

블로그 게시물 MVVM CommandReference 및 KeyBinding 참조


이 코드를 사용해보십시오 ...

먼저 RoutedComand 객체를 만듭니다.

  RoutedCommand newCmd = new RoutedCommand();
  newCmd.InputGestures.Add(new KeyGesture(Key.N, ModifierKeys.Control));
  CommandBindings.Add(new CommandBinding(newCmd, btnNew_Click));

사용하려는 위치에 따라 다릅니다.

TextBoxBase파생 컨트롤은 이미 해당 바로 가기를 구현합니다. 사용자 정의 키보드 단축키를 사용하려면 명령 및 입력 제스처를 살펴보십시오. 다음은 Switch on the Code 의 작은 자습서입니다 . WPF 자습서-명령 바인딩 및 사용자 지정 명령


거의 참조 할 수없고 XAML을 전혀 건드릴 필요가없는 훨씬 간단한 방법이 있기 때문에 다른 사람을 위해이 답변을 문서화하십시오.

키보드 단축키를 연결하려면 Window 생성자에서 InputBindings 컬렉션에 새 KeyBinding을 추가하기 만하면됩니다. 명령으로 ICommand를 구현하는 임의의 명령 클래스를 전달하십시오. execute 메소드의 경우 필요한 로직을 간단히 구현하십시오. 아래 예제에서 WindowCommand 클래스는 호출 될 때마다 실행될 대리자를 가져옵니다. 바인딩과 함께 전달할 새 WindowCommand를 구성 할 때 WindowCommand를 실행하려는 메서드를 이니셜 라이저에 표시하면됩니다.

이 패턴을 사용하여 빠른 단축키를 만들 수 있습니다.

public YourWindow() //inside any WPF Window constructor
{
   ...
   //add this one statement to bind a new keyboard command shortcut
   InputBindings.Add(new KeyBinding( //add a new key-binding, and pass in your command object instance which contains the Execute method which WPF will execute
      new WindowCommand(this)
      {
         ExecuteDelegate = TogglePause //REPLACE TogglePause with your method delegate
      }, new KeyGesture(Key.P, ModifierKeys.Control)));
   ...
}

실행 델리게이트가 메소드 세트를 실행하도록하는 간단한 WindowCommand 클래스를 작성하십시오.

public class WindowCommand : ICommand
{
    private MainWindow _window;

    //Set this delegate when you initialize a new object. This is the method the command will execute. You can also change this delegate type if you need to.
    public Action ExecuteDelegate { get; set; }

    //You don't have to add a parameter that takes a constructor. I've just added one in case I need access to the window directly.
    public WindowCommand(MainWindow window)
    {
        _window = window;
    }

    //always called before executing the command, mine just always returns true
    public bool CanExecute(object parameter)
    {
        return true; //mine always returns true, yours can use a new CanExecute delegate, or add custom logic to this method instead.
    }

    public event EventHandler CanExecuteChanged; //i'm not using this, but it's required by the interface

    //the important method that executes the actual command logic
    public void Execute(object parameter)
    {
        if (ExecuteDelegate != null)
        {
            ExecuteDelegate();
        }
        else
        {
            throw new InvalidOperationException();
        }
    }
}

I had a similar problem and found @aliwa's answer to be the most helpful and most elegant solution; however, I needed a specific key combination, Ctrl + 1. Unfortunately I got the following error:

'1' cannot be used as a value for 'Key'. Numbers are not valid enumeration values.

With a bit of further search, I modified @aliwa's answer to the following:

<Window.InputBindings>
    <KeyBinding Gesture="Ctrl+1" Command="{Binding MyCommand}"/>
</Window.InputBindings>

I found this to work great for pretty well any combination I needed.


VB.NET:

Public Shared SaveCommand_AltS As New RoutedCommand

Inside the loaded event:

SaveCommand_AltS.InputGestures.Add(New KeyGesture(Key.S, ModifierKeys.Control))

Me.CommandBindings.Add(New CommandBinding(SaveCommand_AltS, AddressOf Me.save))

No XAML is needed.


Although the top answers are correct, I personally like to work with attached properties to enable the solution to be applied to any UIElement, especially when the Window is not aware of the element that should be focused. In my experience I often see a composition of several view models and user controls, where the window is often nothing more that the root container.

Snippet

public sealed class AttachedProperties
{
    // Define the key gesture type converter
    [System.ComponentModel.TypeConverter(typeof(System.Windows.Input.KeyGestureConverter))]
    public static KeyGesture GetFocusShortcut(DependencyObject dependencyObject)
    {
        return (KeyGesture)dependencyObject?.GetValue(FocusShortcutProperty);
    }

    public static void SetFocusShortcut(DependencyObject dependencyObject, KeyGesture value)
    {
        dependencyObject?.SetValue(FocusShortcutProperty, value);
    }

    /// <summary>
    /// Enables window-wide focus shortcut for an <see cref="UIElement"/>.
    /// </summary>
    // Using a DependencyProperty as the backing store for FocusShortcut.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty FocusShortcutProperty =
        DependencyProperty.RegisterAttached("FocusShortcut", typeof(KeyGesture), typeof(AttachedProperties), new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.None, new PropertyChangedCallback(OnFocusShortcutChanged)));

    private static void OnFocusShortcutChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        if (!(d is UIElement element) || e.NewValue == e.OldValue)
            return;

        var window = FindParentWindow(d);
        if (window == null)
            return;

        var gesture = GetFocusShortcut(d);
        if (gesture == null)
        {
            // Remove previous added input binding.
            for (int i = 0; i < window.InputBindings.Count; i++)
            {
                if (window.InputBindings[i].Gesture == e.OldValue && window.InputBindings[i].Command is FocusElementCommand)
                    window.InputBindings.RemoveAt(i--);
            }
        }
        else
        {
            // Add new input binding with the dedicated FocusElementCommand.
            // see: https://gist.github.com/shuebner20/349d044ed5236a7f2568cb17f3ed713d
            var command = new FocusElementCommand(element);
            window.InputBindings.Add(new InputBinding(command, gesture));
        }
    }
}

With this attached property you can define a focus shortcut for any UIElement. It will automatically register the input binding at the window containing the element.

Usage (XAML)

<TextBox x:Name="SearchTextBox"
         Text={Binding Path=SearchText}
         local:AttachedProperties.FocusShortcutKey="Ctrl+Q"/>

Source code

The full sample including the FocusElementCommand implementation is available as gist: https://gist.github.com/shuebner20/c6a5191be23da549d5004ee56bcc352d

Disclaimer: You may use this code everywhere and free of charge. Please keep in mind, that this is a sample that is not suitable for heavy usage. For example, there is no garbage collection of removed elements because the Command will hold a strong reference to the element.


How to associate the command with a MenuItem:

<MenuItem Header="My command" Command="{x:Static local:MyWindow.MyCommand}"/>

참고URL : https://stackoverflow.com/questions/1361350/keyboard-shortcuts-in-wpf

반응형