Skip to: Site menu | Main content

Email Facebook LinkedIn Twitter Google

Blog...

<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:

Screenshot 1

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:

Screenshot 2

Sometimes Flex is too easy!

Comments (Comment Moderation is enabled. Your comment will not appear until approved.)
Thanks for posting this, I was having the same problem.
# Posted By John | 7/27/07 8:11 PM
Awesome, it was starting to drive me crazy, it works just fine but now I have a bit of a difficulty.

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.
# Posted By James | 2/17/09 12:36 AM
Have you tried creating a MenuBar dynamically are runtime using

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
# Posted By James | 2/17/09 12:44 AM
As most things go, after a full day of work I finally got it working as it should.

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.
# Posted By James | 2/17/09 1:44 AM
@James. Thanks so much for the comments and code samples looks like you solved this one before I even woke up :)
# Posted By Jason Holden | 2/17/09 6:13 AM
BlogCFC was created by Raymond Camden. This blog is running version 5.9.1.001.