Adobe Flex 3 Help

Defining menu structure and data

All menu-based controls use data providers with the following characteristics to specify the structure and contents of the menus:

  • The data providers are often hierarchical, but you can also have a single-level menu.
  • Individual menu items include fields that determine the menu item appearance and behavior. Menu-based controls support fields that define the label text, an icon, the menu item type, and item status. For information on meaningful fields, see Specifying and using menu entry information.

About menu data providers

The dataProvider property of a menu-based control specifies an object that defines the structure and contents of the menu. If a menu's contents are dynamic, you change the menu by modifying its data provider.

Menu-based controls typically get their data from hierarchical data providers, such as nested arrays of objects or XML. If the menu represents dynamically changing data, you use an object that implements the ICollectionView interface, such as ArrayCollection or XMLListCollection.

Menu-based controls use a data descriptor to parse and manipulate the data provider contents. By default, menu-based controls use a DefaultDataDescriptor class descriptor, but you can create your own class and specify it in the Menu control's dataDescriptor property.

The DefaultDataDescriptor class supports the following types of data:

XML 

A string that contains valid XML text, or any of the following objects containing valid E4X format XML data: an <mx:XML> or <mx:XMLList> compile-time tag, or an XML or XMLList object.



Other objects 

An array of items, or an object that contains an array of items, where a node's children are contained in an item named children. You can also use the <mx:Model> compile-time tag to create nested objects that support data binding, but you must follow the structure defined in Using the <mx:Model> tag with Tree and menu-based controls.



Collections  

An object that implements the ICollectionView interface (such as the ArrayCollection or XMLListCollection classes) and whose data source conforms to the structure specified in either of the previous bullets. The DefaultDataDescriptor class includes code to handle collections efficiently. Always use a collection as the data provider if the data in the menu changes dynamically; otherwise, the Menu displays obsolete data.



For more information on hierarchical objects and data descriptors, including a detailed description of the formats supported by the DefaultDataDescriptor, see Data descriptors and hierarchical data structure.

As with all data-driven controls, if the data provider contents can change dynamically, and you want the Menu to update with the changes, ensure that the data source is a collection, such as an ArrayCollection or XMLListCollection object. To modify the menu, change the underlying collection, and the menu will update its appearance accordingly.

Node (menu item) tags in the XML data can have any name. Many examples in this topic use tags such as <node> for all menu items, or <menuItem> for top-level items and <subMenuItem> for submenu items, but it might be more realistic to use tag names that identify the data, such as <person>, <address>, and so on. The menu-handling code reads through the XML and builds the display hierarchy based on the nested relationship of the nodes. For more information, see Specifying and using menu entry information.

Most menus have multiple items at the top level, not a single root item. XML objects, such as the XML object created by the <mx:XML> tag, must have a single root node. To display a menu that uses a data provider that has a root that you do not want to display, set the Menu, PopUpMenuButton, or MenuBar showRoot property to false.

Specifying and using menu entry information

Information in menu-based control data providers determines how each menu entry appears and is used. To access or change the menu contents, you modify the contents of the data provider.

The menu-based classes use the methods of the IMenuDataDescriptor interface to access and manipulate information in the data provider that defines the menu behavior and contents. Flex provides a DefaultDataDescriptor class that implements this interface. The menu-based controls use the DefaultDataDescriptor class if you do not set the dataDescriptor property.

Menu entry types

Each data provider entry can specify an item type and type-specific information about the menu item. Menu-based classes support the following item types (type field values):

normal 

(the default) Selecting an item with the normal type triggers a change event, or, if the item has children, opens a submenu.



check 

Selecting an item with the check type toggles the menu item's toggled property between true and false values. When the menu item is in the true state, it displays a check mark in the menu next to the item's label.



radio  

Items with the radio type operate in groups, much like RadioButton controls; you can select only one radio menu item in each group at a time. The example in this section defines three submenu items as radio buttons within the group "one".



When a radio button is selected, the radio item's toggled property is set to true, and the toggled properties of all other radio items in the group are set to false. The Menu control displays a solid circle next to the radio button that is currently selected. The selection property of the radio group is set to the label of the selected menu item.

separator 

Items with the separator type provide a simple horizontal line that divides the items in a menu into different visual groups.



Menu attributes

Menu items can specify several attributes that determine how the item is displayed and behaves. The following table lists the attributes you can specify, their data types, their purposes, and how the data provider must represent them if the menu uses the DefaultDataDescriptor class to parse the data provider:

Attribute

Type

Description

enabled

Boolean

Specifies whether the user can select the menu item (true), or not (false). If not specified, Flex treats the item as if the value were true.

If you use the default data descriptor, data providers must use an enabled XML attribute or object field to specify this characteristic.

groupName

String

(Required, and meaningful, for radio type only) The identifier that associates radio button items in a radio group. If you use the default data descriptor, data providers must use a groupName XML attribute or object field to specify this characteristic.

icon

Class

Specifies the class identifier of an image asset. This item is not used for the check, radio, or separator types. You can use the checkIcon and radioIcon styles to specify the icons used for radio and check box items that are selected.

The menu's iconField or iconFunction property determines the name of the field in the data that specifies the icon, or a function for determining the icons.

label

String

Specifies the text that appears in the control. This item is used for all menu item types except separator.

The menu's labelField or labelFunction property determines the name of the field in the data that specifies the label, or a function for determining the labels. (If the data provider is in E4X XML format, you must specify one of these properties to display a label.) If the data provider is an array of strings, Flex uses the string value as the label.

toggled

Boolean

Specifies whether a check or radio item is selected. If not specified, Flex treats the item as if the value were false and the item is not selected.

If you use the default data descriptor, data providers must use a toggled XML attribute or object field to specify this characteristic.

type

String

Specifies the type of menu item. Meaningful values are separator, check, or radio. Flex treats all other values, or nodes with no type entry, as normal menu entries.

If you use the default data descriptor, data providers must use a type XML attribute or object field to specify this characteristic.

Menu-based controls ignore all other object fields or XML attributes, so you can use them for application-specific data.

Example: An Array menu data provider

The following example displays a Menu that uses an Array data provider and shows how you define the menu characteristics in the data provider. For an application that specifies an identical menu structure in XML, see Example: Creating a simple Menu control.

<?xml version="1.0"?>
<!-- menus/ArrayDataProvider.mxml -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" 
    layout="absolute">

    <mx:Script>
        <![CDATA[
            import mx.controls.Menu;

            // Method to create an Array-based menu. 
            private function createAndShow():void {
                // The third parameter sets the showRoot property to false.
                // You must set this property in the createMenu method, 
                // not later.
                var myMenu:Menu = Menu.createMenu(null, menuData, true);
                myMenu.show(10, 10);
            }

            // The Array data provider
            [Bindable] 
            public var menuData:Array = [
                {label: "MenuItem A", children: [
                    {label: "SubMenuItem A-1", enabled: false},
                    {label: "SubMenuItem A-2", type: "normal"} 
                    ]},
                {label: "MenuItem B", type: "check", toggled: true},
                {label: "MenuItem C", type: "check", toggled: false},
                {type: "separator"},
                {label: "MenuItem D", children: [
                    {label: "SubMenuItem D-1", type: "radio", 
                        groupName: "g1"},
                    {label: "SubMenuItem D-2", type: "radio", 
                        groupName: "g1", toggled: true}, 
                    {label: "SubMenuItem D-3", type: "radio", 
                        groupName: "g1"} 
                    ]} 
                ];
        ]]>
    </mx:Script>

    <!-- Button control to create and open the menu. -->
    <mx:Button x="300" y="10" 
        label="Open Menu" 
        click="createAndShow();"/>
</mx:Application>

The executing SWF file for the previous example is shown below:

The following image shows the resulting control, with MenuItem D open; notice that check item B and radio item D-2 are selected:

Menu control, with MenuItem D

Example: An XML menu data provider with icons

The following example displays a menu control that uses XML as the data provider, and specifies custom icons for the items in the control:

<?xml version="1.0"?>
<!-- SimpleMenuControlIcon.mxml -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" >

    <mx:Script>
        <![CDATA[
            // Import the Menu control.
            import mx.controls.Menu;
    
            [Bindable]
            [Embed(source="assets/topIcon.jpg")]
            public var myTopIcon:Class;
    
            [Bindable]
            [Embed(source="assets/radioIcon.jpg")]
            public var myRadioIcon:Class;
    
            [Bindable]
            [Embed(source="assets/checkIcon.gif")]
            public var myCheckIcon:Class;

            // Create and display the Menu control.
            private function createAndShow():void {
                var myMenu:Menu = Menu.createMenu(null, myMenuData, false);
                myMenu.labelField="@label";

                // Specify the check icon.
                myMenu.setStyle('checkIcon', myCheckIcon);

                // Specify the radio button icon.
                myMenu.setStyle('radioIcon', myRadioIcon);

                // Specify the icon for the topmenu items.
                myMenu.iconField="@icon";
                myMenu.show(10, 10);
            }
        ]]>
    </mx:Script>

    <!-- Define the menu data. -->
    <mx:XML format="e4x" id="myMenuData">
        <root>
            <menuitem label="MenuItem A" icon="myTopIcon">
                <menuitem label="SubMenuItem A-1" enabled="false"/>
                <menuitem label="SubMenuItem A-2"/>
            </menuitem>
            <menuitem label="MenuItem B" type="check" toggled="true"/>
            <menuitem label="MenuItem C" type="check" toggled="false" 
                icon="myTopIcon"/>
            <menuitem type="separator"/>     
            <menuitem label="MenuItem D" icon="myTopIcon">
                <menuitem label="SubMenuItem D-1" type="radio" 
                    groupName="one"/>
                <menuitem label="SubMenuItem D-2" type="radio" 
                    groupName="one" toggled="true"/>
                <menuitem label="SubMenuItem D-3" type="radio" 
                    groupName="one"/>
            </menuitem>
        </root>
    </mx:XML>

    <mx:VBox>
        <!-- Define a Button control to open the menu -->
        <mx:Button id="myButton" 
            label="Open Menu" 
            click="createAndShow();"/>
    </mx:VBox>
</mx:Application>

The executing SWF file for the previous example is shown below: