|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
|
Announcements
Chapters
Services
Feature Zones
|
IntroductionThis sample code allows the user to customize the shortcuts assigned to menu-items. The shortcuts get stored in the user.confg. Therefore, the application can be used in multi-user environments. When the application gets started, a list with all menu items is created. This list is bound to a listbox where the user can select a menu item. After selecting, the shortcut for this menu item can be assigned or modified. On closing the application, the assigned shortcuts get stored in the user.config. On re-start, these shortcuts from the user.config are read and assigned to the menus. BackgroundShortcuts are a bitwise combination of the keys used for the shortcut. So, it's is possible to combine keys to a shortcut by using OR. To get the keys used for a shortcut, eliminate the known keys, building the shortcut by using XOR. To save the shortcuts permanently, the VS provided settings are used. For binding the settings (a list of shortcuts), an List of all menu itemsGetting the list of all menu itemsA recursive method is used to fill the list with all the menu items of the form. The recursion is done by checking if a menu item has dropdown items, i.e., is a parent to other menu items. private List<ToolStripMenuItem> menuItemsList = new List<ToolStripMenuItem>();
private void FillListWithMenuEntries(ToolStripItemCollection items)
{
foreach (ToolStripMenuItem item in items)
{
menuItemsList.Add(item);
// Verify if this item is a parent for other menu-items.
// If so add these children by recursion:
if (item.HasDropDownItems)
FillListWithMenuEntries(item.DropDownItems);
}
}
Binding the list with menu items to a ListboxThe lstMenuItems.DataSource = menuItemsList;
lstMenuItems.DisplayMember = "Text";
Class providing a list of keysThe built-in enumeration /// <summary>
/// Class for use in the List of Keys
/// </summary>
public class Key
{
/// <summary>
/// Name of the Key
/// </summary>
public string Name { get; set; }
/// <summary>
/// KeyCode of the key. ReadOnly.
/// </summary>
public Keys KeyCode
{
get
{
KeysConverter keyConverter = new KeysConverter();
return (Keys)keyConverter.ConvertFrom(this.Name);
}
}
}
To provide the list, I've implemented another class. This class has the /// <summary>
/// Class providing a list with Keys for selection
/// </summary>
public class KeysList
{
#region Properties
/// <summary>
/// ReadOnly by private set (for automatic properties in .net 3.5)
/// </summary>
public List<Key> KeyList { get; private set; }
#endregion
//---------------------------------------------------------------------
#region Contructor
/// <summary>
/// Initializes the KeyList with the selectable keys for the
/// shortcuts (A-Z, F1-F11)
/// </summary>
public KeysList()
{
this.KeyList = new List<Key>();
// Letters A-Z:
for (byte b = 65; b <= 90; b++)
{
// Convert ASCII to character:
char c = Convert.ToChar(b);
// Add to list:
this.KeyList.Add(new Key { Name = c.ToString() });
}
// Add F-keys (F1-F11):
for (byte b = 1; b <= 11; b++)
this.KeyList.Add(new Key { Name = "F" + b.ToString() });
}
#endregion
}
The letters A-Z are represented by ASCII-code 65-90. Via This list is bound to a combobox for user's selection. cmbKeys.DataSource = new KeysList().KeyList;
cmbKeys.DisplayMember = "Name";
cmbKeys.ValueMember = "KeyCode";
Combine a shortcutAs stated above: shortcuts are a bitwise combination of modifiers and keys. The modifiers are selected by checking (or unchecking) a checkbox. The combination is done by OR-operations. Keys shortCut = (Keys)cmbKeys.SelectedValue;
if (chkCtrl.Checked) shortCut |= Keys.Control;
if (chkAlt.Checked) shortCut |= Keys.Alt;
if (chkShift.Checked) shortCut |= Keys.Shift;
Following the rules of the boolean algebra, the order of combination doesn't matter. For querying whether this selected/combined shortcut is already assigned, I've used a LINQ-query to the list of all menu items. var query = menuItemsList.FirstOrDefault(s => s.ShortcutKeys == shortCut);
By using Retrieving the key and the modifiersThe reverse way: get the key and the modifiers that are combined to a shortcut. For getting the modifiers, we can bit-mask the shortcut and check if the result is equal to a possible modifier. Bit-masking is done by AND. In this operation, the values of the checkboxes are set. Keys shortCut = selectedItem.ShortcutKeys;
chkCtrl.Checked = (shortCut & Keys.Control) == Keys.Control;
chkAlt.Checked = (shortCut & Keys.Alt) == Keys.Alt;
chkShift.Checked = (shortCut & Keys.Shift) == Keys.Shift;
To get the letter or the F-key, we have to eliminate the modifiers. This is done by combining all the set modifiers and then by removing them from the shortcut with XOR. Example (values used are just dummies to show how it works): Ctrl = 00100000
Alt = 01000000 OR
-------------------
modifyer = 01100000
shortcut = 01100010
modifyer = 01100000 XOR
-------------------
Key = 00000010
Code: Keys modifiers = Keys.None;
if (chkCtrl.Checked) modifiers |= Keys.Control;
if (chkAlt.Checked) modifiers |= Keys.Alt;
if (chkShift.Checked) modifiers |= Keys.Shift;
Keys buchstabe = shortCut ^ modifiers;
Saving the shortcutsThis is done by using the VS built-in Settings-designer. From the possible types, the designer provides an array list that is chosen. On private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
// For saving the shortcut in user.config they have to be
// written in an ArrayList. Only the shortcuts are saved:
ArrayList arrList = new ArrayList(menuItemsList.Count);
foreach (ToolStripMenuItem item in menuItemsList)
arrList.Add(item.ShortcutKeys);
Properties.Settings.Default.ShortCuts = arrList;
}
In Program.cs: Application.Run(new Form1());
// Save the settings:
Properties.Settings.Default.Save();
On startupBy saving the settings, the values are written to the user.config file. On startup, these values have to be assigned to the menu items. This done by creating a list of the menu items and then by assigning the values of the shortcuts. // Get ShortCuts from the saved user-settings (user.config):
ArrayList arrList = Properties.Settings.Default.ShortCuts;
if (arrList != null)
for (int i = 0; i < menuItemsList.Count; i++)
menuItemsList[i].ShortcutKeys = (Keys)arrList[i];
Generally: Using the codeThe sample is a full working project. When used in your application, you have to adjust the code to your user interface. See the comments in the code for details. Points of interestCombining and retrieving the keys used for a shortcut by using bit-manipulation with OR and XOR. See alsoComponent for customizing menu shortcuts describes a component that allows the customization of menu shortcuts. This can be useful for barrier free aspplications. HistoryThis is the first release. Inspired by request in a forum. The code is made up form scratch. There maybe some improvements in future.
|
||||||||||||||||||||||