Лучший подход для добавления клавиатуры "Горячие клавиши / горячие клавиши" для управления моим приложением - PullRequest
0 голосов
/ 05 марта 2019

Я работаю над настольным приложением, в котором я хочу позволить пользователю контролировать его функциональные возможности с помощью клавиатуры, а также разрешить ему менять стандартные контроллеры на пользовательские контроллеры в соответствии с его точкой зрения.

Мой вопрос: каков наилучший подход для решения этой проблемы и обеспечения надлежащего решения этой проблемы?

1 Ответ

0 голосов
/ 05 марта 2019

Вы можете использовать Словарь , чтобы привязать каждый ключ к действию

Мой подход здесь заключается в использовании Словарь , где Ключ является фактической клавиатурой Ключи и значение int? представляют одну из ваших функций, которые могут быть связаны с пользовательским вводом.

Dictionnary<Keys, int?> shortcutDictionnary = new Dictionary<Keys, int?>();
// Add a new Keys
shortcutDictionary.Add(Keys.A, 1);
// Change a Keys value (change shortcut bounded to it)
shortcutDictionary[Keys.A] = 4;

Для соответствия этим int? с этими функциями вам нужно использовать только switch :

int? num = null;
if (this.shortcutDictionary.TryGetValue(keyPressed, out num))
{
    switch (num)
    {
        case 1:
            attack();
            break;
        case 2:
            defend();
            break;
        case 3:
            hide();
            break;
        case 4:
            dance();
            break;
        default:
            Console.WriteLine("Key not bounded");
            break;
    }
}

Я также в своем коде ниже использую enum вместо прямого использования Keys для моего словаря .
Таким образом, я могу выбрать, какие Ключи могут быть ограничены, а какие нет.

Мой код сделан из приложения Winform, в качестве примера я использовал только 4 Ключи (A, B, C, D), которые можно связать, и один, чтобы легко изменить привязку (L), но я уверен, что вы можете понять, как легко изменить границу любым другим методом.Кроме того, так как я работаю с WindowsForm, мне пришлось установить KeyPreview = true.
Вот мой код:

using System;
using System.Collections.Generic;
using System.Windows.Forms;

namespace Project
{
    public enum UsableKeys
    {
        A = Keys.A,
        B = Keys.B,
        C = Keys.C,
        D = Keys.D,
    }

    public partial class Form1 : Form
    {
        Dictionary<UsableKeys, int?> shortcutDictionary = new Dictionary<UsableKeys, int?>();

        public Form1()
        {
            InitializeComponent();

            foreach (UsableKeys key in Enum.GetValues(typeof(UsableKeys)))
            {
                // You may add default shortcut here
                this.shortcutDictionary.Add(key, null);
            }
        }

        private void Form1_KeyDown(object sender, KeyEventArgs e)
        {
            UsableKeys keyPressed = (UsableKeys)e.KeyCode;
            if (this.shortcutDictionary.ContainsKey(keyPressed))
            {
                executeAction(keyPressed);

                e.Handled = true;
                e.SuppressKeyPress = true;
            }
            else if (e.KeyCode == Keys.L)
            {
                switch (this.shortcutDictionary[UsableKeys.A])
                {
                    case 1:
                        this.shortcutDictionary[UsableKeys.A] = 4;
                        this.shortcutDictionary[UsableKeys.B] = 3;
                        this.shortcutDictionary[UsableKeys.C] = 2;
                        this.shortcutDictionary[UsableKeys.D] = 1;
                        break;
                    case null:
                        this.shortcutDictionary[UsableKeys.A] = 1;
                        this.shortcutDictionary[UsableKeys.B] = 2;
                        this.shortcutDictionary[UsableKeys.C] = 3;
                        this.shortcutDictionary[UsableKeys.D] = 4;
                        break;
                    case 4:
                        this.shortcutDictionary[UsableKeys.A] = null;
                        this.shortcutDictionary[UsableKeys.B] = null;
                        this.shortcutDictionary[UsableKeys.C] = null;
                        this.shortcutDictionary[UsableKeys.D] = null;
                        break;
                }

                e.Handled = true;
                e.SuppressKeyPress = true;
            }
        }

        private void executeAction(UsableKeys keyPressed)
        {
            int? num = null;
            if (this.shortcutDictionary.TryGetValue(keyPressed, out num))
            {
                switch (num)
                {
                    case 1:
                        attack();
                        break;
                    case 2:
                        defend();
                        break;
                    case 3:
                        hide();
                        break;
                    case 4:
                        dance();
                        break;
                    default:
                        Console.WriteLine("Key not bounded");
                        break;
                }
            }
        }

        private void attack()
        {
            Console.WriteLine("Player swing his word");
        }

        private void defend()
        {
            Console.WriteLine("Player raise his shield");
        }

        private void hide()
        {
            Console.WriteLine("Player sneak around");
        }

        private void dance()
        {
            Console.WriteLine("Player start to dance");
        }
    }
}

С этим кодом вывод будет выглядеть следующим образом:

// Press A, B, C or D
"Key not bounded"
// Press L
// Press A
"Player swing his word"
// Press B
"Player raise his shield"
// Press C
"Player sneak around"
// Press D
"Player start to dance"
// Press L
// Press A
"Player start to dance"
// Press B
"Player sneak around"
// Press C
"Player raise his shield"
// Press D
"Player swing his sword"
// Press L
// Press A, B, C or D
"Key not bounded"

Пример изменения привязки ключа во время выполнения:

// Create a new Dictionary for shortcuts
Dictionary<UsableKeys, int?> shortcutDictionary = new Dictionary<UsableKeys, int?>();
// Add a pair key/value that bind A to attack()
shortcutDictionary.Add(UsableKey.A, 1);
// Add a pair Key/value that bind B to defend()
shortcutDictionary.Add(UsableKey.B, 2);
// Now, if you press A, attack() will be called
shortcutDictionary[UsableKey.A] = 2;
// Now if you press A or B, defend() will be called
shortcutDictionary[UsableKey.B] = null;
// Now B isn't bind to any function, so only A is binded to defend();

С помощью этого метода вы не можете привязать несколько функций к одной Ключи , в то время как вы можете привязать несколько Ключей к одной функции (Если вы хотите инвертировать это, просто поменяйте местами клавишу / значение Словарь и скорректируйте код в соответствии с этим).
Я не знаю, является ли это оптимальным способом сделать это, но это не код спагетти, и он хорошо работает.

...