添加键盘 "Shortcuts/Hotkeys" 来控制我的应用程序的最佳方法
Best approach to add keyboard "Shortcuts/Hotkeys" to control my application
我正在开发一个桌面应用程序,我希望允许用户通过键盘控制它的功能,还允许他根据自己的观点将默认控制器更改为自定义控制器。
我的问题是,解决此问题并提供适当解决方案的最佳方法是什么?
您可以使用 字典 将每个键绑定到一个动作
我的方法是使用 Dictionary,其中 Key 是实际的 Keybord Keys,value 是 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 作为我的 Dictionary。
这样,我可以选择哪些 Keys 可以被绑定,哪些不能。
我的代码是用一个Winform应用程序做的,作为一个例子我只用了4个Keys (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();
使用此方法,您不能将多个函数绑定到一个 Keys,而可以将多个 Keys 绑定到一个函数(如果你想反转它,只需交换 Dictionary 的 key/value 并调整代码以匹配它)。
我不知道这是否是执行此操作的最佳方法,但它不是意大利面条代码,而且效果很好。
我正在开发一个桌面应用程序,我希望允许用户通过键盘控制它的功能,还允许他根据自己的观点将默认控制器更改为自定义控制器。
我的问题是,解决此问题并提供适当解决方案的最佳方法是什么?
您可以使用 字典 将每个键绑定到一个动作
我的方法是使用 Dictionary,其中 Key 是实际的 Keybord Keys,value 是 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 作为我的 Dictionary。
这样,我可以选择哪些 Keys 可以被绑定,哪些不能。
我的代码是用一个Winform应用程序做的,作为一个例子我只用了4个Keys (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();
使用此方法,您不能将多个函数绑定到一个 Keys,而可以将多个 Keys 绑定到一个函数(如果你想反转它,只需交换 Dictionary 的 key/value 并调整代码以匹配它)。
我不知道这是否是执行此操作的最佳方法,但它不是意大利面条代码,而且效果很好。