功能实现对特定功能的快捷键设置,用户自行修改并保存修改后的快捷键方式,加入快捷键冲突检测,防止相同的快捷键被分配给多个功能,保存快捷键到json文件中。

主界面:

实现快捷键的映射及按下相应快捷键的执行逻辑。

using ShortcutTest.Common;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace ShortcutTest
{
	public partial class MainForm : Form
	{
		private ShortcutManager _shortcutManager = new ShortcutManager();
		private Dictionary<Keys, string> _keyFunctionMap = new Dictionary<Keys, string>();
		private bool _isShortcutInitialized = false; // 添加标志变量
		public MainForm()
		{
			InitializeComponent();
			InitializeShortcuts();
		}
		private void InitializeShortcuts()
		{
			// 重建快捷键映射
			_keyFunctionMap.Clear();
			var shortcuts = _shortcutManager.GetAllShortcuts();
			foreach (var shortcut in shortcuts)
			{
				// 确保不重复映射相同的快捷键
				if (!_keyFunctionMap.ContainsKey(shortcut.Value))
				{
					_keyFunctionMap[shortcut.Value] = shortcut.Key;
				}
				else
				{
					// 处理快捷键冲突
					MessageBox.Show($"快捷键冲突: {shortcut.Value} 已被 {_keyFunctionMap[shortcut.Value]} 使用");
				}
			}

			// 确保事件只注册一次
			this.KeyPreview = true;
			if (!_isShortcutInitialized)
			{
				this.KeyDown += MainForm_KeyDown;
				_isShortcutInitialized = true;
			}
		}

		private void MainForm_KeyDown(object sender, KeyEventArgs e)
		{
			if (_keyFunctionMap.TryGetValue(e.KeyData, out string functionName))
			{
				ExecuteShortcutFunction(functionName);
				e.Handled = true;
				e.SuppressKeyPress = true;
			}
		}

		private void ExecuteShortcutFunction(string functionName)
		{
			switch (functionName)
			{
				case ShortcutManager.SaveFile:
					SaveFileFunction();
					break;
				case ShortcutManager.OpenFile:
					OpenFileFunction();
					break;
				case ShortcutManager.Copy:
					CopyFunction();
					break;
				case ShortcutManager.Paste:
					PasteFunction();
					break;
				case ShortcutManager.Undo:
					UndoFunction();
					break;
				case ShortcutManager.Redo:
					RedoFunction();
					break;
				default:
					MessageBox.Show($"未定义的快捷键功能: {functionName}");
					break;
			}
		}

		// 具体的功能实现
		private void SaveFileFunction()
		{
			// 保存文件逻辑
			MessageBox.Show("保存文件快捷键触发");
		}

		private void OpenFileFunction()
		{
			// 打开文件逻辑
			MessageBox.Show("打开文件快捷键触发");
		}

		private void CopyFunction()
		{
			// 复制逻辑
			MessageBox.Show("复制快捷键触发");
		}

		private void PasteFunction()
		{
			// 粘贴逻辑
			MessageBox.Show("粘贴快捷键触发");
		}

		private void UndoFunction()
		{
			// 撤销逻辑
			MessageBox.Show("撤销快捷键触发");
		}

		private void RedoFunction()
		{
			// 重做逻辑
			MessageBox.Show("重做快捷键触发");
		}

		// 打开快捷键设置对话框
		private void btnShortcutSettings_Click(object sender, EventArgs e)
		{
			using (var form = new ShortcutSettingsForm(_shortcutManager))
			{
				if (form.ShowDialog() == DialogResult.OK)
				{
					// 重新加载快捷键
					InitializeShortcuts();
				}
			}
		}
		public void ReloadShortcuts()
		{
			InitializeShortcuts();
		}
	}
}

快捷键设置界面:

实现对当前快捷键的显示、对特定功能进行自定义快捷键、通知主窗体重新加载快捷键等功能。

using ShortcutTest.Common;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace ShortcutTest
{
	public partial class ShortcutSettingsForm : Form
	{
		private ShortcutManager _shortcutManager;
		private Dictionary<string, TextBox> _textBoxMap = new Dictionary<string, TextBox>();
		public ShortcutSettingsForm(ShortcutManager shortcutManager)
		{
			InitializeComponent();
			_shortcutManager = shortcutManager;
			InitializeControls();
		}
		private void InitializeControls()
		{
			var shortcuts = _shortcutManager.GetAllShortcuts();

			int yPos = 20;
			foreach (var shortcut in shortcuts)
			{
				// 添加标签
				var label = new Label
				{
					Text = GetFunctionDisplayName(shortcut.Key),
					Location = new System.Drawing.Point(20, yPos),
					Width = 100
				};

				// 添加文本框显示当前快捷键
				var textBox = new TextBox
				{
					Text = shortcut.Value.ToString(),
					Location = new System.Drawing.Point(130, yPos),
					Width = 150,
					Tag = shortcut.Key,
					ReadOnly = true
				};

				// 添加设置按钮
				var button = new Button
				{
					Text = "设置",
					Location = new System.Drawing.Point(290, yPos),
					Tag = shortcut.Key
				};
				button.Click += SetShortcutButton_Click;

				this.Controls.Add(label);
				this.Controls.Add(textBox);
				this.Controls.Add(button);

				_textBoxMap[shortcut.Key] = textBox;

				yPos += 40;
			}

			// 添加确定和取消按钮
			var btnOk = new Button { Text = "确定", Location = new System.Drawing.Point(100, yPos + 20) };
			var btnCancel = new Button { Text = "取消", Location = new System.Drawing.Point(200, yPos + 20) };

			btnOk.Click += (s, e) => { this.DialogResult = DialogResult.OK; this.Close(); };
			btnCancel.Click += (s, e) => { this.DialogResult = DialogResult.Cancel; this.Close(); };

			this.Controls.Add(btnOk);
			this.Controls.Add(btnCancel);

			this.Height = yPos + 100;
		}

		private string GetFunctionDisplayName(string functionName)
		{
			var displayNames = new Dictionary<string, string>
		{
			{ ShortcutManager.SaveFile, "保存文件" },
			{ ShortcutManager.OpenFile, "打开文件" },
			{ ShortcutManager.Copy, "复制" },
			{ ShortcutManager.Paste, "粘贴" },
			{ ShortcutManager.Undo, "撤销" },
			{ ShortcutManager.Redo, "重做" }
		};

			return displayNames.TryGetValue(functionName, out string displayName) ? displayName : functionName;
		}

		private void SetShortcutButton_Click(object sender, EventArgs e)
		{
			var button = (Button)sender;
			var functionName = (string)button.Tag;

			using (var form = new KeyCaptureForm(_shortcutManager.GetShortcut(functionName)))
			{
				if (form.ShowDialog() == DialogResult.OK && form.SelectedKeys != Keys.None)
				{
					// 使用新的设置方法,返回是否成功
					if (_shortcutManager.SetShortcut(functionName, form.SelectedKeys))
					{
						_textBoxMap[functionName].Text = form.SelectedKeys.ToString();

						// 通知主窗体重新加载快捷键
						if (this.Owner is MainForm mainForm)
						{
							mainForm.ReloadShortcuts();
						}
					}
				}
			}
		}
	}

	// 快捷键捕获窗体
	public partial class KeyCaptureForm : Form
	{
		public Keys SelectedKeys { get; private set; }
		private Label _keyLabel;
		private Label _infoLabel;

		public KeyCaptureForm(Keys currentKeys)
		{
			//InitializeComponent();
			SelectedKeys = currentKeys;
			InitializeControls();
		}

		private void InitializeControls()
		{
			this.Text = "设置快捷键";
			this.KeyPreview = true;
			this.FormBorderStyle = FormBorderStyle.FixedDialog;
			this.StartPosition = FormStartPosition.CenterParent;
			this.Size = new System.Drawing.Size(300, 200);

			_infoLabel = new Label
			{
				Text = "按下新的快捷键组合:",
				Dock = DockStyle.Top,
				Height = 30,
				TextAlign = System.Drawing.ContentAlignment.MiddleCenter
			};

			_keyLabel = new Label
			{
				Text = SelectedKeys.ToString(),
				Dock = DockStyle.Fill,
				TextAlign = System.Drawing.ContentAlignment.MiddleCenter,
				Font = new System.Drawing.Font("Microsoft Sans Serif", 12),
				ForeColor = System.Drawing.Color.Blue
			};

			var panel = new Panel { Dock = DockStyle.Fill };
			panel.Controls.Add(_keyLabel);
			panel.Controls.Add(_infoLabel);

			var btnOk = new Button { Text = "确定", Dock = DockStyle.Bottom, Height = 30 };
			var btnCancel = new Button { Text = "取消", Dock = DockStyle.Bottom, Height = 30 };

			btnOk.Click += (s, e) =>
			{
				if (SelectedKeys != Keys.None)
				{
					this.DialogResult = DialogResult.OK;
					this.Close();
				}
				else
				{
					MessageBox.Show("请先设置一个有效的快捷键");
				}
			};

			btnCancel.Click += (s, e) => { this.DialogResult = DialogResult.Cancel; this.Close(); };

			this.Controls.Add(panel);
			this.Controls.Add(btnCancel);
			this.Controls.Add(btnOk);
		}

		protected override void OnKeyDown(KeyEventArgs e)
		{
			base.OnKeyDown(e);

			// 忽略单独的修饰键
			if (e.KeyCode == Keys.ControlKey || e.KeyCode == Keys.ShiftKey ||
				e.KeyCode == Keys.Menu || e.KeyCode == Keys.LWin || e.KeyCode == Keys.RWin)
			{
				return;
			}

			SelectedKeys = e.KeyData;
			_keyLabel.Text = SelectedKeys.ToString();
			e.Handled = true;
			e.SuppressKeyPress = true;
		}
	}
}

快捷键管理类:

快捷键设置的核心代码,实现获取快捷键、快捷键冲突检测、加载及保存快捷键。

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Newtonsoft.Json;
using Formatting = System.Xml.Formatting;

namespace ShortcutTest.Common
{
	public class ShortcutManager
	{
		private static readonly string ConfigFile = "shortcuts.json";
		private Dictionary<string, Keys> _shortcuts = new Dictionary<string, Keys>();

		// 预定义的快捷键功能
		public const string SaveFile = "SaveFile";
		public const string OpenFile = "OpenFile";
		public const string Copy = "Copy";
		public const string Paste = "Paste";
		public const string Undo = "Undo";
		public const string Redo = "Redo";

		public ShortcutManager()
		{
			LoadDefaultShortcuts();
			LoadCustomShortcuts();
		}

		private void LoadDefaultShortcuts()
		{
			_shortcuts[SaveFile] = Keys.Control | Keys.S;
			_shortcuts[OpenFile] = Keys.Control | Keys.O;
			_shortcuts[Copy] = Keys.Control | Keys.C;
			_shortcuts[Paste] = Keys.Control | Keys.V;
			_shortcuts[Undo] = Keys.Control | Keys.Z;
			_shortcuts[Redo] = Keys.Control | Keys.Y;
		}

		public Keys GetShortcut(string functionName)
		{
			return _shortcuts.TryGetValue(functionName, out Keys keys) ? keys : Keys.None;
		}

		public Dictionary<string, Keys> GetAllShortcuts()
		{
			return new Dictionary<string, Keys>(_shortcuts);
		}

		private void SaveCustomShortcuts()
		{
			try
			{
				var json = JsonConvert.SerializeObject(_shortcuts, (Newtonsoft.Json.Formatting)Formatting.Indented);
				File.WriteAllText(ConfigFile, json);
			}
			catch (Exception ex)
			{
				MessageBox.Show($"保存快捷键配置失败: {ex.Message}");
			}
		}

		private void LoadCustomShortcuts()
		{
			if (File.Exists(ConfigFile))
			{
				try
				{
					var json = File.ReadAllText(ConfigFile);
					var loaded = JsonConvert.DeserializeObject<Dictionary<string, Keys>>(json);
					if (loaded != null)
					{
						foreach (var item in loaded)
						{
							if (_shortcuts.ContainsKey(item.Key))
							{
								_shortcuts[item.Key] = item.Value;
							}
						}
					}
				}
				catch (Exception ex)
				{
					MessageBox.Show($"加载快捷键配置失败: {ex.Message}");
				}
			}
		}

		// 添加冲突检测方法
		public bool HasConflict(string excludeFunction, Keys keys)
		{
			if (keys == Keys.None) return false;

			return _shortcuts.Any(x =>
				x.Key != excludeFunction &&
				x.Value == keys);
		}

		public string GetConflictFunction(string excludeFunction, Keys keys)
		{
			return _shortcuts.FirstOrDefault(x =>
				x.Key != excludeFunction &&
				x.Value == keys).Key;
		}

		// 修改设置方法,添加冲突检查
		public bool SetShortcut(string functionName, Keys keys, bool force = false)
		{
			if (keys == Keys.None)
			{
				MessageBox.Show("不能设置为空快捷键");
				return false;
			}

			// 检查冲突
			if (!force && HasConflict(functionName, keys))
			{
				var conflictFunction = GetConflictFunction(functionName, keys);
				var result = MessageBox.Show(
					$"快捷键 {keys} 已被 {conflictFunction} 使用,是否强制覆盖?",
					"快捷键冲突",
					MessageBoxButtons.YesNo);

				if (result != DialogResult.Yes)
				{
					return false;
				}
			}

			if (_shortcuts.ContainsKey(functionName))
			{
				_shortcuts[functionName] = keys;
			}
			else
			{
				_shortcuts.Add(functionName, keys);
			}

			SaveCustomShortcuts();
			return true;
		}
	}
}

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐