using System; using System.Collections.Generic; using System.Windows.Forms; using DevExpress.XtraEditors; namespace Lskj.Control.Model { /// /// 将按钮原有的 & 助记键改为必须按 Alt 才能触发的快捷键。 /// public sealed class AltButtonShortcutManager { private sealed class ShortcutItem { public SimpleButton Button; public Keys Key; } private readonly List mShortcutItems = new List(); private bool mUpdatingText; /// /// 注册按钮快捷键,并移除标题中的 &,保持界面显示为“按钮名(X)”。 /// public void Register(SimpleButton button, Keys defaultKey) { if (button == null) { return; } ShortcutItem item = mShortcutItems.Find( shortcut => ReferenceEquals(shortcut.Button, button)); if (item == null) { item = new ShortcutItem { Button = button, Key = defaultKey }; mShortcutItems.Add(item); button.TextChanged += OnButtonTextChanged; } UpdateShortcut(item, defaultKey); } /// /// 只响应 Alt+原助记键;未按 Alt、同时按下其他修饰键时均不处理。 /// public bool ProcessKey(Keys keyData) { if ((keyData & Keys.Modifiers) != Keys.Alt) { return false; } Keys keyCode = keyData & Keys.KeyCode; foreach (ShortcutItem item in mShortcutItems) { SimpleButton button = item.Button; if (item.Key == keyCode && button != null && !button.IsDisposed && button.Visible && button.Enabled) { button.PerformClick(); return true; } } return false; } private void OnButtonTextChanged(object sender, EventArgs e) { if (mUpdatingText) { return; } SimpleButton button = sender as SimpleButton; ShortcutItem item = mShortcutItems.Find( shortcut => ReferenceEquals(shortcut.Button, button)); if (item != null) { UpdateShortcut(item, item.Key); } } private void UpdateShortcut(ShortcutItem item, Keys defaultKey) { string text = item.Button.Text ?? string.Empty; int mnemonicIndex = FindMnemonicIndex(text); if (mnemonicIndex >= 0) { item.Key = (Keys)char.ToUpperInvariant(text[mnemonicIndex + 1]); mUpdatingText = true; try { item.Button.Text = text.Remove(mnemonicIndex, 1); } finally { mUpdatingText = false; } } else { item.Key = defaultKey; } } private static int FindMnemonicIndex(string text) { for (int index = 0; index < text.Length - 1; index++) { if (text[index] == '&' && char.IsLetterOrDigit(text[index + 1])) { return index; } } return -1; } } }