Uniform management of WPF shortcuts and uniform management of wpf shortcuts
Recently, I just changed my job. When I got to the new company, I received my first project, working as a branch retail POS system. The customer has high requirements on the interface, so WPF is used as the client development technology. In the POS system, shortcut keys are important functions. Many shortcut keys are similar in function implementation. WPF needs to configure InputBindings on each page. To facilitate maintenance and development, it is necessary to manage shortcuts in a unified manner. Now let me introduce the implementation.
To achieve unified management, my idea is to make the shortcut key configurable. Secondly, I can automatically bind the shortcut key and process the handle according to the configuration. Not much nonsense.
1. KeyboardShortcuts Shortcut Key Management Portal
public class KeyboardShortcuts { private const string COFINGFILE = "KeyboardShortcutsRule.Config"; public KeyboardShortcuts() { Rules = new List<KeyboardShortcutsRule>(); LoadConfig(); } public List<KeyboardShortcutsRule> Rules { get; set; } public void ActiveKeysBindings(Window window) { foreach (var item in Rules) { if (!item.IgnoreWindow.Contains(window.GetType())) { if (item.Effectivity.Count == 0 || item.Effectivity.Contains(window.GetType())) { window.InputBindings.Add(new InputBinding(item.Command.GetCommand(), new KeyGestureConverter().ConvertFromString(item.Keys) as KeyGesture) { CommandParameter = window }); } } } } private static KeyboardShortcuts current = null; public static KeyboardShortcuts Current { get { if (current == null) { current = new KeyboardShortcuts(); } return current; } } public void LoadConfig() { try { XDocument doc = XDocument.Load(COFINGFILE); this.Rules = doc.Element("Settings").Elements("KeyboardShortcuts") .Select(o => new KeyboardShortcutsRule() { Name = o.Attribute("Name").Value, IsShowInHelp = o.Attribute("IsShowInHelp") != null ? Convert.ToBoolean(o.Attribute("IsShowInHelp").Value) : true, Keys = o.Attribute("Keys").Value, IgnoreWindow = new List<Type>().InitListType(o.Elements("Ignore")), Effectivity = new List<Type>().InitListType(o.Elements("Effect")), Command = o.Attribute("Command").Value.InitCommand() } ).ToList(); } catch { } } public void SaveConfig() { try { XDocument doc = new XDocument(); var element = new XElement("Settings"); foreach (var item in Rules) { var cmdType = item.Command.GetType(); XElement node = new XElement( "KeyboardShortcuts", new XAttribute("Name", item.Name), new XAttribute("Keys", item.Keys), new XAttribute("IsShowInHelp", item.IsShowInHelp), new XAttribute("Command", string.Format("{0}|{1}", cmdType.Assembly.FullName, cmdType.ToString()))); foreach (var childItem in item.IgnoreWindow) { XElement ignoreList = new XElement("Ignore", childItem); node.Add(ignoreList); } foreach (var childItem in item.Effectivity) { XElement effectList = new XElement("Effect", childItem); node.Add(effectList); } element.Add(node); } doc.Add(element); doc.Save(COFINGFILE); } catch { } } }
2. Configure rule entities with shortcuts
public class KeyboardShortcutsRule { public KeyboardShortcutsRule() { IsShowInHelp = true; } public string Name { get; set; } public string Keys { get; set; } public bool IsShowInHelp { get; set; } public List<Type> IgnoreWindow { get; set; } public List<Type> Effectivity { get; set; } public IKeyboardShortcutsCommand Command { get; set; } }
3. xml to linq Extension
public static class LinqExtensions { public static List<Type> InitListType(this List<Type> _this, IEnumerable<XElement> ignoreNodes) { if (_this == null) _this = new List<Type>(); foreach (var item in ignoreNodes) { _this.Add(Assembly.GetExecutingAssembly().GetType(item.Value)); } return _this; } public static IKeyboardShortcutsCommand InitCommand(this string _this) { var results = _this.Split("|".ToCharArray(), StringSplitOptions.RemoveEmptyEntries); if (results.Count() == 2) { return Assembly.Load(results[0]).CreateInstance(results[1]) as IKeyboardShortcutsCommand; } else { return Assembly.GetExecutingAssembly().CreateInstance(results[0]) as IKeyboardShortcutsCommand; } } }
4. Shortcut Key Processing command interface [the object implementing this interface will be automatically triggered after the shortcut key is bound, and PosCommand implements the ICommand interface of WPF]
public interface IKeyboardShortcutsCommand { PosCommand GetCommand(); string Describe { get; set; } }
5. PosCommand implements the ICommand interface of WPF.
public class PosCommand : ICommand { public PosCommand() { } public PosCommand(Action func) { Processor = func; } public PosCommand(Action func, string describe) { Processor = func; Describe = describe; } public PosCommand(Action<object> func, string describe) { ProcessorForParameter = func; Describe = describe; } public string Describe { get; set; } public Action Processor { get; set; } public Action<object> ProcessorForParameter { get; set; } public bool CanExecute(object parameter) { if (Processor != null) return true; if (ProcessorForParameter != null) { return true; } return false; } public void Execute(object parameter) { if (Processor != null) Processor(); if (ProcessorForParameter != null) ProcessorForParameter(parameter); } public event EventHandler CanExecuteChanged; }
6. Implement the shortcut key binding command
Public class HelpCommand: IKeyboardShortcutsCommand {public HelpCommand () {Describe = "help";} public PosCommand GetCommand () {return new PosCommand (o) ==>{ Help page = new Help (); page. show () ;}, Describe) ;}public string Describe {get; set ;}}
7. Configuration
<?xml version="1.0" encoding="utf-8"?><Settings> <KeyboardShortcuts Name="Help" Keys="F1" IsShowInHelp="true" Command="Pharos.POS.Retailing.HelpCommand"> <Ignore>Pharos.POS.Retailing.Login</Ignore> </KeyboardShortcuts> <KeyboardShortcuts Name="ExitSystem" Keys="Alt+F4" Command="Pharos.POS.Retailing.ExitSystemCommand"> <Effect>Pharos.POS.Retailing.MainWindow</Effect> <Effect>Pharos.POS.Retailing.Login</Effect> </KeyboardShortcuts> <KeyboardShortcuts Name="LockScreen" Keys="Ctrl+D" Command="Pharos.POS.Retailing.LockScreenCommand"> <Effect>Pharos.POS.Retailing.MainWindow</Effect> </KeyboardShortcuts> <KeyboardShortcuts Name="Cannel" Keys="Escape" Command="Pharos.POS.Retailing.CannelCommand"></KeyboardShortcuts></Settings>
8. Reference and enable shortcut key settings
Public static class extends wextensions {public static void InitPublicSettings (this Window _ this) {// activate the shortcut key KeyboardShortcuts. Current. ActiveKeysBindings (_ this );}}
public partial class Login : Window { public Login() { InitializeComponent(); this.InitPublicSettings(); } }
In summary, the advantage of doing so is to make it easy to customize shortcut keys. You only need to implement IKeyboardShortcutsCommand and configure the rule document. But it also brings security issues. Anyone who wants to know the mechanism here can use the reflection mechanism of the shortcut key, inject program Trojans, and so on. Even if they do not understand computer programming, deleting the configuration file also causes invalid shortcuts.