/// <summary> /// Load a list of keyboard shortcuts from a file. The list of available actions is also needed to map the shortcuts to these actions. /// </summary> /// <param name="file">The file to load from.</param> /// <param name="list">A list of actions available to be accessed via keyboard shortcuts.</param> /// <returns>A list of keyboard shortcuts, which can be loaded into a KeyRegistry.</returns> /// <exception cref="FileNotFoundException">Thrown if the file does not exist.</exception> /// <remarks>If there is a shortcut in this file that reference an action ID that isn't on the <paramref name="list"/>, then that shortcut is skipped.</remarks> public static List <KeyboardShortcut> LoadFromFile(string file, KeyActionList list) { if (!File.Exists(file)) { throw new FileNotFoundException("The specified file does not exist. Keyboard shortcuts cannot be loaded.", file); } List <KeyboardShortcut> entries = new List <KeyboardShortcut>(); XmlReader xr = XmlReader.Create(file); xr.MoveToContent(); while (xr.Read()) { if (xr.NodeType == XmlNodeType.Element) { //xr.ReadStartElement("ks"); #if NETCOREAPP string?c = xr.GetAttribute("comb"); string?k = xr.GetAttribute("keyid"); string?m = xr.GetAttribute("action"); #else string c = xr.GetAttribute("comb"); string k = xr.GetAttribute("keyid"); string m = xr.GetAttribute("action"); #endif if (string.IsNullOrEmpty(m)) { m = xr.GetAttribute("methodid"); } if (string.IsNullOrEmpty(c) || string.IsNullOrEmpty(k) || string.IsNullOrEmpty(m)) { // skip item } else if (Enum.TryParse(c, out KeyboardCombination kc)) { // try to load keys by their internal integer value // from https://docs.microsoft.com/en-us/dotnet/api/system.windows.input.key?view=net-5.0 (the middle column) if (int.TryParse(k, out int kv)) { #if NETCOREAPP IKeyAction?a = null; #else IKeyAction a = null; #endif if (list != null) { // checks the key action list for "Xxx", "mnuXxx", and "btnXxx" // this is a carryover from internal usage, but I figure it should still be helpful // if desired, I can remove this or make a toggle for it in a future release if (list.ContainsId(m)) { a = list[m]; } else if (list.ContainsId("mnu" + m)) { m = "mnu" + m; a = list[m]; } else if (list.ContainsId("btn" + m)) { m = "btn" + m; a = list[m]; } } if (a != null) { KeyboardShortcut ke = new KeyboardShortcut(kc, (Key)kv, a); entries.Add(ke); } } else { // if the integer-based value doesn't work, try to parse based upon the name of the Key in the enum // again from https://docs.microsoft.com/en-us/dotnet/api/system.windows.input.key?view=net-5.0 (the left column) if (Enum.TryParse(k, out Key kz)) { #if NETCOREAPP IKeyAction?a = null; #else IKeyAction a = null; #endif if (list != null) { // checks the key action list for "Xxx", "mnuXxx", and "btnXxx" // this is a carryover from internal usage, but I figure it should still be helpful // if desired, I can remove this or make a toggle for it in a future release if (list.ContainsId(m)) { a = list[m]; } else if (list.ContainsId("mnu" + m)) { m = "mnu" + m; a = list[m]; } else if (list.ContainsId("btn" + m)) { m = "btn" + m; a = list[m]; } } if (a != null) { KeyboardShortcut ke = new KeyboardShortcut(kc, kz, a); entries.Add(ke); } } } } //xr.ReadEndElement(); } } xr.Close(); return(entries); }
public KeyboardShortcutEventArgs(KeyboardShortcut shortcut) { KeyboardShortcut = shortcut; }