连接到mx.controls.PopUpButton的菜单不会改变 [英] Menu attached to mx.controls.PopUpButton never changes
问题描述
请将下面的2个文件放到Flash Builder 4.6项目中,然后立即运行。我的问题是附加到我的(稍微修改)自定义PopUpButton的菜单永远不会改变 - 即使当您单击3个按钮之一时更改基础数组数据提供程序在其右侧:
AuxButtonTest.mxml:
< ;?xml version =1.0encoding =utf-8?>
xmlns:fx =http://ns.adobe.com/mxml/2009
xmlns:s =library://ns.adobe.com / flex / spark
xmlns:mx =library://ns.adobe.com/flex/mx
xmlns:comps =*
creationComplete =init() >
< fx:Script>
<![CDATA [
import mx.controls.Alert;
导入mx.events.FlexEvent;
private const XML1:XML =
< pref>
< aux event =1>一个< / aux>
< aux event =2>两个< / aux>
< aux event =3>三< / aux>
< aux event =4>四< / aux>
< aux event =5> Five< / aux>
< / pref>;
private const XML2:XML =
< pref>
< aux event =1>一个< / aux>
< aux event =2>两个< / aux>
< / pref>;
private const XML3:XML =
< pref>
< aux event =3>三< / aux>
< / pref>;
public function init():void {
_auxBtn.update(XML1.aux);
$ b $ // private function handleAuxChosen(event:PrefEvent):void {
//Alert.show(event.toString());
//}
]]>
< / fx:Script>
< s:controlBarContent>
<! - - 注释:aux_chosen =handleAuxChosen(event) - >
< comps:AuxButton id =_ auxBtn/>
< / s:controlBarContent>
< / s:Application>
AuxButton.mxml (基于PopUpButton的自定义组件) p>
<?xml version =1.0encoding =utf-8?>
< mx:PopUpButton
xmlns:fx =http://ns.adobe.com/mxml/2009
xmlns:s =library://ns.adobe.com / flex / spark
xmlns:mx =library://ns.adobe.com/flex/mx
popUp ={_ menu}
creationComplete =init(event) >
< fx:元数据>
<! - [Event(name =aux_chosen,type =PrefEvent)] - >
< / fx:元数据>
< fx:Script>
<![CDATA [
import mx.controls.Menu;
导入mx.events.MenuEvent;
导入mx.events.FlexEvent;
private var _str:String;
[Bindable]
private var _data:Array = new Array();
[Bindable]
private var _menu:Menu = new Menu();
private function init(event:FlexEvent):void {
_menu.dataProvider = _data;
_menu.addEventListener('itemClick',handleMenu);
addEventListener('click',handleClick);
public function update(xlist:XMLList):void {
_data.length = 0;
(var xml:xlist中的XML){
_data.push({label:xml,event:xml。@ event});
}
label = _data [0] .label;
_str = _data [0] .event;
enabled = true;
private function handleMenu(event:MenuEvent):void {
label = event.label;
_str = event.item.event;
private function handleClick(event:MouseEvent):void {
enabled = false;
// dispatchEvent(new PrefEvent(PrefEvent.AUX_CHOSEN,_str));
}
]]>
< / fx:Script>
< / mx:PopUpButton>
我已经评论了我的自定义事件 - 这里没关系。 b
$ b
请点击按钮几次,然后看菜单 - 它总是有5个项目,这是错误的。
更新:谢谢你的答案 - 下面的代码现在适用于我。我仍然想知道为什么不支持ArrayList,但是ArrayCollection可以正常工作。
AuxButtonText.mxml:
<?xml version =1.0encoding =utf-8?>
< mx:PopUpButton
xmlns:fx =http://ns.adobe.com/mxml/2009
xmlns:s =library://ns.adobe.com / flex / spark
xmlns:mx =library://ns.adobe.com/flex/mx
popUp ={_ menu}
creationComplete =init(event) >
< fx:Script>
<![CDATA [
import mx.controls。*;
导入mx.events。*;
导入mx.collections。*;
private var _str:String;
[Bindable]
private var _data:ArrayCollection = new ArrayCollection();
// private var _data:ArrayList = new ArrayList();
[Bindable]
private var _menu:Menu = new Menu();
private function init(event:FlexEvent):void {
_menu.dataProvider = _data;
_menu.addEventListener('itemClick',handleMenu);
addEventListener('click',handleClick);
public function update(xlist:XMLList):void {
_data.removeAll();
if(xlist == null || xlist.length()== 0){
enabled = false;
return;
(xml:xml中的XML)
_data.addItem({label:xml,event:xml。@ event});
label = _data.getItemAt(0).label;
_str = _data.getItemAt(0).event;
enabled = true;
private function handleMenu(event:MenuEvent):void {
label = event.label;
_str = event.item.event;
private function handleClick(event:MouseEvent):void {
enabled = false;
// dispatchEvent(new PrefEvent(PrefEvent.AUX_CHOSEN,_str));
}
]]>
< / fx:Script>
< / mx:PopUpButton>
AuxButton.mxml:
<?xml version =1.0encoding =utf-8?>
xmlns:fx =http://ns.adobe.com/mxml/2009
xmlns:s =library://ns.adobe.com / flex / spark
xmlns:mx =library://ns.adobe.com/flex/mx
xmlns:comps =*
initialize =init() >
< fx:Script>
<![CDATA [
private const XML1:XML =
< pref>
< aux event =1>一个< / aux>
< aux event =2>两个< / aux>
< aux event =3>三< / aux>
< aux event =4>四< / aux>
< aux event =5> Five< / aux>
< / pref>;
private const XML2:XML =
< pref>
< aux event =1>一个< / aux>
< aux event =2>两个< / aux>
< / pref>;
private const XML3:XML =
< pref>
< aux event =3>三< / aux>
< / pref>;
private const XML4:XML =
< pref>
< / pref>;
public function init():void {
_auxBtn.update(XML1.aux);
}
]]>
< / fx:Script>
< s:controlBarContent>
< comps:AuxButton id =_ auxBtn/>
< / s:controlBarContent>
< / s:Application>
当数组内容发生变化时,数组不会发送任何事件。作为一个经验法则:在数组上使用 [Bindable]
并将其用作某种dataProvider通常是一个坏主意,因为添加/删除不发送任何事件,因此不会被任何组件处理。
而不是 Array
使用 ArrayCollection
它在内容发生变化时调度类型为 CollectionEvent.COLLECTION_CHANGE
的事件。 Flex SDK中的大多数组件处理这些事件并相应地进行更新。所以,下面的代码工作,因为分配一个新的源
到 ArrayCollection
调度一个 CollectionEvent
导致菜单
更新其菜单项。
//在_data
上不需要[Bindable] private var _data:ArrayCollection = new ArrayCollection();
public function update(xlist:XMLList):void
{
var items:Array = [];
(xml:xml中的XML)
{
items.push({label:xml,event:xml。@ event});
}
_data.source = items;
if(items.length> 0)
{
label = items [0] .label;
_str = items [0] .event;
}
enabled = true;
}
I have prepared a very simple test case to demo my problem.
Please just place the 2 files below into a Flash Builder 4.6 project and they will run instantly.
My problem is that the menu attached to my (slightly modified) custom PopUpButton never changes - even though the underlying Array data provider is changed when you click one of the 3 buttons on the right side of it:
AuxButtonTest.mxml:
<?xml version="1.0" encoding="utf-8"?>
<s:Application
xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
xmlns:comps="*"
creationComplete="init()">
<fx:Script>
<![CDATA[
import mx.controls.Alert;
import mx.events.FlexEvent;
private const XML1:XML =
<pref>
<aux event="1">One</aux>
<aux event="2">Two</aux>
<aux event="3">Three</aux>
<aux event="4">Four</aux>
<aux event="5">Five</aux>
</pref>;
private const XML2:XML =
<pref>
<aux event="1">One</aux>
<aux event="2">Two</aux>
</pref>;
private const XML3:XML =
<pref>
<aux event="3">Three</aux>
</pref>;
public function init():void {
_auxBtn.update(XML1.aux);
}
//private function handleAuxChosen(event:PrefEvent):void {
//Alert.show(event.toString());
//}
]]>
</fx:Script>
<s:controlBarContent>
<!-- commented: aux_chosen="handleAuxChosen(event)" -->
<comps:AuxButton id="_auxBtn" />
<s:Button id="_btn1" label="XML 1" click="_auxBtn.update(XML1.aux);" />
<s:Button id="_btn2" label="XML 2" click="_auxBtn.update(XML2.aux);" />
<s:Button id="_btn3" label="XML 3" click="_auxBtn.update(XML3.aux);" />
</s:controlBarContent>
</s:Application>
AuxButton.mxml (my custom component based on PopUpButton):
<?xml version="1.0" encoding="utf-8"?>
<mx:PopUpButton
xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
popUp="{_menu}"
creationComplete="init(event)">
<fx:Metadata>
<!-- [Event(name="aux_chosen", type="PrefEvent")] -->
</fx:Metadata>
<fx:Script>
<![CDATA[
import mx.controls.Menu;
import mx.events.MenuEvent;
import mx.events.FlexEvent;
private var _str:String;
[Bindable]
private var _data:Array = new Array();
[Bindable]
private var _menu:Menu = new Menu();
private function init(event:FlexEvent):void {
_menu.dataProvider = _data;
_menu.addEventListener('itemClick', handleMenu);
addEventListener('click', handleClick);
}
public function update(xlist:XMLList):void {
_data.length = 0;
for each (var xml:XML in xlist) {
_data.push({label: xml, event: xml.@event});
}
label = _data[0].label;
_str = _data[0].event;
enabled = true;
}
private function handleMenu(event:MenuEvent):void {
label = event.label;
_str = event.item.event;
}
private function handleClick(event:MouseEvent):void {
enabled = false;
//dispatchEvent(new PrefEvent(PrefEvent.AUX_CHOSEN, _str));
}
]]>
</fx:Script>
</mx:PopUpButton>
I've commented my custom event out - it doesn't matter here.
Please just click at the buttons few times and then look at the menu - it always has 5 items and that is wrong.
UPDATE: Thank you for the answers - the following code works now for me. I still wonder why isn't ArrayList supported, but ArrayCollection works fine.
AuxButtonText.mxml:
<?xml version="1.0" encoding="utf-8"?>
<mx:PopUpButton
xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
popUp="{_menu}"
creationComplete="init(event)">
<fx:Script>
<![CDATA[
import mx.controls.*;
import mx.events.*;
import mx.collections.*;
private var _str:String;
[Bindable]
private var _data:ArrayCollection = new ArrayCollection();
//private var _data:ArrayList = new ArrayList();
[Bindable]
private var _menu:Menu = new Menu();
private function init(event:FlexEvent):void {
_menu.dataProvider = _data;
_menu.addEventListener('itemClick', handleMenu);
addEventListener('click', handleClick);
}
public function update(xlist:XMLList):void {
_data.removeAll();
if (xlist == null || xlist.length() == 0) {
enabled = false;
return;
}
for each (var xml:XML in xlist)
_data.addItem({label: xml, event: xml.@event});
label = _data.getItemAt(0).label;
_str = _data.getItemAt(0).event;
enabled = true;
}
private function handleMenu(event:MenuEvent):void {
label = event.label;
_str = event.item.event;
}
private function handleClick(event:MouseEvent):void {
enabled = false;
//dispatchEvent(new PrefEvent(PrefEvent.AUX_CHOSEN, _str));
}
]]>
</fx:Script>
</mx:PopUpButton>
AuxButton.mxml:
<?xml version="1.0" encoding="utf-8"?>
<s:Application
xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
xmlns:comps="*"
initialize="init()">
<fx:Script>
<![CDATA[
private const XML1:XML =
<pref>
<aux event="1">One</aux>
<aux event="2">Two</aux>
<aux event="3">Three</aux>
<aux event="4">Four</aux>
<aux event="5">Five</aux>
</pref>;
private const XML2:XML =
<pref>
<aux event="1">One</aux>
<aux event="2">Two</aux>
</pref>;
private const XML3:XML =
<pref>
<aux event="3">Three</aux>
</pref>;
private const XML4:XML =
<pref>
</pref>;
public function init():void {
_auxBtn.update(XML1.aux);
}
]]>
</fx:Script>
<s:controlBarContent>
<comps:AuxButton id="_auxBtn" />
<s:Button id="_btn1" label="XML 1" click="_auxBtn.update(XML1.aux);" />
<s:Button id="_btn2" label="XML 2" click="_auxBtn.update(XML2.aux);" />
<s:Button id="_btn3" label="XML 3" click="_auxBtn.update(XML3.aux);" />
<s:Button id="_btn4" label="LEN=0" click="_auxBtn.update(XML4.aux);" />
<s:Button id="_btn5" label="NULL" click="_auxBtn.update(null);" />
</s:controlBarContent>
</s:Application>
Arrays do not dispatch any events when their content changes. As a rule of thumb: Using [Bindable]
on an Array and using it as some kind of dataProvider is usually a bad idea since adding/removing doesn't dispatch any events and therefore won't be handled by any component.
Instead of Array
use an ArrayCollection
which dispatches events of type CollectionEvent.COLLECTION_CHANGE
whenever its content changes. Most components in the Flex SDK handle those events and update itself accordingly. So, the following code works since assigning a new source
to the ArrayCollection
dispatches a CollectionEvent
which causes the Menu
to update its menu items.
// you don't need [Bindable] on _data
private var _data:ArrayCollection = new ArrayCollection();
public function update(xlist:XMLList):void
{
var items:Array = [];
for each (var xml:XML in xlist)
{
items.push({label: xml, event: xml.@event});
}
_data.source = items;
if (items.length > 0)
{
label = items[0].label;
_str = items[0].event;
}
enabled = true;
}
这篇关于连接到mx.controls.PopUpButton的菜单不会改变的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!