<mx:MenuBar> Gotcha.
After almost an hour and some hair pulling I finally figured this one out.
| SCENARIO: | I want to drive a <mx:MenuBar> from an external XML file. |
Easy enough!
Here is my XML:
<root>
<menuitem label="Main Menu 1">
<menuitem label="Menu 1 Command 1"/>
<menuitem label="Menu 1 Command 2"/>
</menuitem>
<menuitem label="Main Menu 2">
<menuitem label="Menu 2 Command 1"/>
</menuitem>
</root>
My MXML:
<mx:MenuBar id="mainMenu" width="100%" labelField="@label">
<mx:XML format="e4x" source="assets/mainmenu.xml"/>
</mx:MenuBar>
No compile errors, but when I run the application i get this:

The answer is so simple, but it eluded me. The <mx:MenuBar> has a showRoot attributes that is true by default.
New code:
<mx:MenuBar id="mainMenu" width="100%" labelField="@label" showRoot="false">
<mx:XML format="e4x" source="assets/mainmenu.xml"/>
</mx:MenuBar>
Fixed:

Sometimes Flex is too easy!



You see the real value for me to use an external xml file to drive the menu bar is to manage program feature accessibility by user login and restrict access to certain menus by it. so the idea of creating a unique xml file (say with userID appended to it ie. menu232.xml) and retrieving it at run time would do the trick right? ... Wrong when I try using <mx:XML id="myExternalXmlMenu" source="{myMenu}"/> I get the error "Data binding expressions not supported with attributes processed at compile time."
Any ideas?
Thanks.
private var menubarXML:XMLList =
it will not access conditional statements such as
[Bindable]
private var myMenuHeading:String = "My Internal Variable";
[Bindable]
private var myMenuItem:String = "My Internal Value";
private var menubarXML:XMLList =
<>
<menuitem label={myMenuHeading}>
<menuitem label={myMenuItem} data={myMenuItem}/>
<menuitem type="separator"/>
<menuitem label="MenuItem 1-B" data="1B"/>
</menuitem>
if(myID == 1){
<menuitem label="Menu 3" enabled="true">
} else {
<menuitem label="Menu 3" enabled="false">
}
<menuitem label="Menu 3">
<menuitem label="MenuItem 2-A" type="check" data="2A"/>
<menuitem label="MenuItem 2-B" >
<menuitem label="SubMenuItem 3-A" type="radio" groupName="one" data="3A"/>
<menuitem label="SubMenuItem 3-B" type="radio" groupName="one" data="3B"/>
</menuitem>
<menuitem type="separator" />
<menuitem label="type=check" id="ch" type="check" toggled="true" />
<menuitem label="type=check" id="ch" type="check" toggled="true" enabled="false" />
<menuitem type="separator" />
<menuitem label="1) type=radio" type="radio" groupName="radioGroup" toggled="true" />
<menuitem label="2) type=radio" type="radio" groupName="radioGroup" />
<menuitem label="3) type=radio" type="radio" groupName="radioGroup" />
<menuitem label="4) type=radio" type="radio" groupName="radioGroup" enabled="false" />
</menuitem>
</>;
It doe not compile, any thoughts?
Thanks again
Dynamic menus can be built using the following AS Code:
[Bindable]
private var myRuntimeMenu:XML;
//build your own runtime menu xml file
private function buildXml():void{
var ids:Array = ["Menu 1", "Menu 2", "Menu 3"];
var names:Array = [["File","Edit"], ["Copy","Paste"], ["About","Window"]]
myRuntimeMenu= new XML("<xmlRoot></xmlRoot>");
for (var i:int = 0; i < 3; i++)
{
var newnode:XML = new XML();
newnode =
<menuitem label={ids[i]} id={ids[i]}>
<menuitem label={names[i][0]} data={names[i][0]}/>
<menuitem label={names[i][1]} data={names[i][1]}/>
</menuitem>
myRuntimeMenu = myRuntimeMenu.appendChild(newnode)
}
}
Then simply bind your MenuBar as in:
<mx:MenuBar labelField="@label" itemClick="menuHandler(event)" dataProvider="{myRuntimeMenu}" showRoot="false"/>
And you are done, now you can change and edit all menu items at runtime including loading user's profiles and access rights at login.
Hope this helps anybody who has found himself/herself in this predicament.
Thanks.