Flex 3 cookbook: 2.8 动态填充菜单

2.8 动态填充菜单

2.8.1 问题

你想填充并动态改变菜单

2.8.2 解答

ActionScript 分配一个 ArrayCollection XMLListCollection 这样的 Collection 对象给 MenuBar 控件的 dataProvider 属性。

2.8.3 讨论

Flex 3 里的 MenuBar 控件支持在运行时动态生成菜单项。下面的代码生成一个有 MenuBar 控件的应用,当应用被初始化时,这个 MenuBar 被一个 ArrayCollecton 对象填充。

 

<mx:Application
    xmlns:mx="http://www.adobe.com/2006/mxml"
    layout="vertical"
    creationComplete="initApp(event)">

    <mx:MenuBar id="menu" dataProvider="{menu_dp}"/>

    <mx:Script>
        <![CDATA[
            import mx.collections.ArrayCollection;
            import mx.events.FlexEvent;

            [Bindable]
            private var menu_dp:ArrayCollection;

            private function initApp(evt:FlexEvent):void {
                var temp:Array = new Array();

                var subNodes:ArrayCollection = new ArrayCollection([{label:"New"},
                                                                      {label:"Open"},
                                                                      {label:"Close",enabled:false}]);
                temp.push({label:"File",children:subNodes});
                temp.push({label:"Edit"});
                temp.push({label:"Source"});

                subNodes = new ArrayCollection([{label:"50%", type:"radio",roupName:"one"},
                                           {label:"100%", type:"radio", groupName:"one",selected:true},
                                           {label:"150%", type:"radio", groupName:"one"}]);
                temp.push({label:"View",children:subNodes});
                menu_dp = new ArrayCollection(temp);
            }
        ]]>
    </mx:Script>
</mx:Application>
 

 

上述代码用 binding 绑定一个名为 menu_dp ArrayCollecton 对象到 MenuBar 组件的 dataProvider 属性。在该应用的 creationComplete 事件发生时, menu_dp 被初始化,并填充菜单项。就像 Flex 里的其它数据驱动组件一样,使用类似 ArrayCollection XMLListCollection Collection 组件,可以确保基础数据的任何变化都会导致控件的显示作相应的刷新。

译者注 : 请将 subNodes 的第二项的 selected 属性改成 toggled 。如 2.7 节所述, toggled 属性才是控制 radio 类型的菜单项是否被选中的。

Collection 组件提供了便利的方法编辑,添加,删除菜单项。为了说明这一点,这个例子在 MenuBar 下添加了一个简单的 Form 组件,让你可以根据他们在 ArrayCollecton 里的索引编辑菜单。

   

 

<mx:Form>
        <mx:FormHeading label="Menu Editor"/>
        <mx:FormItem label="Menu Index">
            <mx:TextInput id="menuIdx" restrict="0-9" text="0" width="20"/>
        </mx:FormItem>
        <mx:FormItem label="Sub-Menu Index">
            <mx:TextInput id="subMenuIdx" restrict="0-9" width="20"/>
        </mx:FormItem>
        <mx:FormItem label="Menu Label">
            <mx:TextInput id="label_ti"/>
        </mx:FormItem>
        <mx:FormItem>
            <mx:Button label="Edit" click="editMenu()"/>
        </mx:FormItem>
    </mx:Form>
 

 

 

这是一个很基础的 Form ,它的 input 控件可以让你指定数组索引,依此来获取一个特定的菜单项。在 menuIdx 文本框里输入 0 ,并保持 subMenuIdx 为空,则指定 File 菜单的顶级。在 menuIdx 文本框里输入 0 ,在 subMenuIdx 里输入 0 ,则指定 New 子菜单项。

当用户单击 Edit 按钮, editMenu 方法就被调用,这个方法用指定的索引来获取某个菜单项的引用并改变它的标签。请看如下代码:

 

private function editMenu():void {
    var itemToEdit:Object;
    try {
        itemToEdit = menu_dp.getItemAt(int(menuIdx.text));
        if(subMenuIdx.text) {
            itemToEdit = itemToEdit.children.getItemAt(int(subMenuIdx.text));
        }
        itemToEdit.label = label_ti.text;
        menu_dp.itemUpdated(itemToEdit);
    }
    catch(ex:Error){
        trace("could not retrieve menu item");
    }
}
 

 

 

editMenu 里的代码查找输入 menuIdx subMenuIdx 里的值,依此去寻找一个特定的菜单项,然后用 label_ti 里的值去刷新那个菜单项显示的内容。注意:为了改变菜单的显示,与 MenuBar 关联的 dataProvider 被改变了,然后用 ArrayCollecton itemUpdated 方法来请求刷新菜单显示。在类似这个例子的嵌套数据结构中,调用 itemUpdated 来请求显示刷新很重要。否则,基础数据改变了,但是显示仍然是旧的内容。示例代码中用了一个 try…catch 块来为数组界限做一些基础的错误处理。

 

你可能感兴趣的:(数据结构,Flex,Adobe,actionscript)