Avg. Rating 4.0

Problem

What do you do if your application needs custom context menus for components that are not at the application level but rather are nested within other containers or components.

Solution

You can change the Application level context menu when an event (such as mouse over) is triggered from your nested component, and reset the Application menu on another event (such as mouse out).

Detailed explanation

According to the Flex documentation, "In Flex, only top-level components in the application can have context menus. For example, if a DataGrid control is a child of a TabNavigator or VBox container, the DataGrid control cannot have its own context menu."

Below is a simple example that changes the Application level context menu when the user mouses over a button nested within an HBOX and resets the context menu when the user mouses off the button.

You can also see the working example here and you can right-click on it to view the source.

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical"
creationComplete="init()"
viewSourceURL="srcview/index.html">
<mx:Script>
<![CDATA[

private var myContextMenuType1:ContextMenu;
private var originalMenu : ContextMenu;
/**
* creates the 'normal' context menu for this application
*/
private function init():void{
Application.application.contextMenu.hideBuiltInItems();
var defaultItems:ContextMenuBuiltInItems = Application.application.contextMenu.builtInItems;
defaultItems.print = true;
var anaaraLinkItem : ContextMenuItem = new ContextMenuItem('Created by Anaara Media LLC');
Application.application.contextMenu.customItems.push(anaaraLinkItem);
anaaraLinkItem.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, goAnaara);
originalMenu = Application.application.contextMenu;
createCustomContextMenus();
}
private function goAnaara(event:ContextMenuEvent):void{
outputLabel.text = 'Brought to you by Anaara Media LLC | www.anaara.com';
}
private function createCustomContextMenus():void{
myContextMenuType1 = new ContextMenu();
myContextMenuType1.hideBuiltInItems();
var menu1Item:ContextMenuItem = new ContextMenuItem('Custom task 1');
myContextMenuType1.customItems.push(menu1Item);
menu1Item.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, menuItemSelectHandler);
}
private function menuItemSelectHandler(event:ContextMenuEvent):void{
trace("menuSelectHandler: " + event);
outputLabel.text = 'custom menu item selected';
}
/* takes an argument to allow for multiple custom context menus... */
private function changeContextMenu(menuType:String):void{
trace('mouseOver');
Application.application.contextMenu = myContextMenuType1;

}
private function resetContextMenu():void{
trace('mouseOut');
Application.application.contextMenu = originalMenu;
}
]]>
</mx:Script>
<mx:HBox>
<mx:Label id="outputLabel" text="These controls are inside an HBOX and therefore not at the application level..." />
<mx:Button label="test button" mouseOver="changeContextMenu('testButton')" mouseOut="resetContextMenu()" />
</mx:HBox>
</mx:Application>


Report abuse

Related recipes