I've had some frustration with Flex ContextMenus, so I thought I'd write an entry about the basics of creating context menus, adding items, listening for context menu events, and a few restrictions on context menus.
Every
InteractiveObject (e.g. Application, Panel, Button, etc) contains a
contextMenu property. For most components it will be null and you'll have to create a new menu and assign it to that property. So you can have different context menus for different components.
Here is a simple example of a context menu set on the application:
Here is a short snippet from the above example showing you have to create a
ContextMenu, hide the built-in menu items, and listen for menu events.
private function initContextMenu():void { // 1. Create the context menu if it doesn't exist // it will exist for the application, but won't for most other components if (!contextMenu) { this.contextMenu = new ContextMenu(); }
// 2. Hide the built-in menu items // (you can't remove the basic 3 or 4 items like: Settings, About, etc) contextMenu.hideBuiltInItems(); // 3. Add menu items, you can optionally set the menu item enablement and // visibility in the ContextMenuItem constructor var firstItem:ContextMenuItem = new ContextMenuItem("Hello there!", true); contextMenu.customItems.push(firstItem); var secondItem:ContextMenuItem = new ContextMenuItem("Disabled"); contextMenu.customItems.push(secondItem); var thirdItem:ContextMenuItem = new ContextMenuItem("Hidden"); contextMenu.customItems.push(thirdItem); // 4. Listen for menu events // this event happens when the context menu is about to show contextMenu.addEventListener(ContextMenuEvent.MENU_SELECT, function(event:ContextMenuEvent):void { // add logic here to determine the visibility or enablement secondItem.enabled = false; thirdItem.visible = false; }); // 5. Handle menu item click events var handler:Function = function(event:ContextMenuEvent):void { Alert.show("You clicked on the menu item '" + event.currentTarget.caption + "'"); }; firstItem.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, handler); secondItem.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, handler); thirdItem.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, handler); } |
There are many
restrictions to Flex ContextMenus, some of which will drive you crazy. Read carefully, it will save you time later.
- Maximum of 15 custom menu items in the menu
- No sub-menus allowed
- No icons in menus
- Menu items must be 100 characters or less
- Control characters, newlines, and other white space characters are ignored
- MANY reserved words including (but not limited to):
- Save
- Zoom In
- Zoom Out
- 100%
- Show All
- Quality
- Play
- Loop
- Rewind
- Forward
- Back
- Movie not loaded
- About
- Print
- Show Redraw Regions
- Debugger
- Undo
- Cut
- Copy
- Paste
- Delete
- Select All
- Open
- Open in new window
- Copy link
- Copy Link Location
- Del
I'm not quite sure why there are so many restrictions, but I'm sure Adobe has a good reason for it!
More details about the restrictions can be found on the
ContextMenuItem page.
There are a few other solutions for people who want more control over the menus. These usually involve adding right click listeners in JavaScript on top of the Flex application and passing that event into Flex to position and show a custom menu instead of the usual Flex context menu.
Here is one such solution:
Custom Context Menu.
These solutions can work quite effectively, but since they depend on the browser they can be quite buggy.