Title: Use ActiveControl to enabled and disable menu items in C#
This program uses the ActiveControl property to determine what menu items should be enabled and disabled at any given moment. When the user opens a menu, only the appropriate items should be enabled. This example has Copy, Cut, and Paste menu items. The following list explains when they should be enabled.
- Copy - Enabled when the active control is a TextBox and some of its text is selected.
- Cut - Enabled when the active control is a TextBox and some of its text is selected.
- Paste - Enabled when the active control is a TextBox and the clipboard contains text.
I have seen programs try to enable and disable menu items in all sorts of ways. Some try to figure out when a condition has changed (such as the user selecting text in a TextBox). Some even use a Timer to enable and disable menus every quarter second. That means the program does a huge amount of checking when nothing hasn't actually changed.
A much easier solution is to enable and disable menu items when the menu is about to display. This example uses the following code to enable and disable its menu items.
private void EnableMenuItems()
{
if (ActiveControl is TextBox)
{
TextBox txt = ActiveControl as TextBox;
mnuEditCopy.Enabled = (txt.SelectionLength > 0);
mnuEditCut.Enabled = (txt.SelectionLength > 0);
mnuEditPaste.Enabled = Clipboard.ContainsText();
}
else
{
// Disable all commands.
mnuEditCopy.Enabled = false;
mnuEditCut.Enabled = false;
mnuEditPaste.Enabled = false;
}
ctxCopy.Enabled = mnuEditCopy.Enabled;
ctxCut.Enabled = mnuEditCut.Enabled;
ctxPaste.Enabled = mnuEditPaste.Enabled;
}
This code is reasonably straightforward. It enables and disables the main menu's Copy, Cut, and Paste commands depending on whether the active control is a TextBox, whether text is selected, and whether the clipboard contains text. It then gives the program's context menu commands the same enabled states as the corresponding main menu commands.
So when do you call the EnableMenuItems method? A form's main menu raises its DropDownOpening event when it is about to open. The following code calls EnableMenuItems when the Edit menu opens.
// Enable and disable items as appropriate.
private void mnuEdit_DropDownOpening(object sender, EventArgs e)
{
EnableMenuItems();
}
This works differently for context menus because in some sense a context menu is the dropdown. Instead of using a context menu's DropDownOpening event, the program looks for its Opening event as in the following code.
private void ctxEdit_Opening(object sender, CancelEventArgs e)
{
EnableMenuItems();
}
Now when a menu or context menu is displayed, its commands are enabled as appropriate.
Note that this technique doesn't work for toolbar commands or other objects that are always visible. In those cases you need to either leave the item enabled and just have it not do anything when the user invokes it, or detect changes to the rest of the program (like when the user selects text) and set the editability accordingly.
Download the example to experiment with it and to see additional details.
|