Flex3:自定义项呈示器不侦听父级调度的事件

时间:2009-04-23 09:26:26

标签: actionscript-3 events flex flex3 itemrenderer

我有一个带有自定义ItemRenderer的List。 ItemRenderer包含一个复选框和一个Label。 具有List的组件具有“全选”复选框。 选中“全选”复选框后,它会调度每个项应该侦听的事件,以便选择自己的复选框。 eventlistener被添加到每个项目的creationComplete上,当选中“全选”复选框时,事件将被正确调度,但自定义ItemRenderer中的监听器不会监听。

如何让ItemRenderer监听在其父级中调度的事件?

我将添加一些代码示例来澄清:

------- container ----------
<mx:VBox>
   <mx:Script>
      <![CDATA[
         public var user1 = new User(1, "Jack");
         public var user2 = new User(2, "John");
         public var user3 = new User(3, "Mary");

         [Bindable]
         public var users:ArrayCollection = new ArrayCollection([user1], [user2], [user3]);

         public static const SELECT_ALL_USERS:String = "selectAllUsers";

         private function selectAllChangeHandler():void
         {
            if (selectAll.selected)
               dispatchEvent(new Event(SELECT_ALL_USERS,true));
         }
      ]]>
   </mx:Script>
   <mx:CheckBox id="selectAll" change="{selectAllChangeHandler()}" />
   <mx:List dataProvider="{users}" itemRenderer="myRenderer" />
</mx:VBox>


------- renderer ----------
<?xml version="1.0" encoding="utf-8"?>
<mx:HBox creationComplete="{init()}">
   <mx:Script>
      <![CDATA[
         private function init():void
         {
            addEventListener (Container.SELECT_ALL, selectAllHandler, false, 0, true);
         }

         private function selectAllHandler():void
         {
            checkbox.selected=true;
         }

         private function selected(id:int):Boolean
         {
             return id==1 || id==3;
         }
      ]]>
   </mx:Script>

   <mx:CheckBox id="checkbox" selected="{selected(data.id)}" />
   <mx:Label text="{data.name}" />
</mx:HBox>

请注意,用户ArrayCollection或其包含的用户对象无法更改,因为我稍后需要这些值。 因此,当单击“selectAll”时,还应检查列表中的每个复选框。

4 个答案:

答案 0 :(得分:2)

您的自定义ItemRenderers不应该使用其父级注册事件监听器,而应使用“全选”复选框,即

theCheckbox.addEventListener(YourEvent.YOUR_EVENT, itemRendererSelectAllHandler);

如果失败了,您可以发布添加事件监听器的代码,并从复选框中调度事件吗?

修改

这是您的错误:在渲染器的init()中,您需要将事件侦听器添加到渲染器,而不是添加到调度事件的容器。所以,做一个

container.addEventListener(Container.SELECT_ALL_USERS, selectAllHandler, false, 0, true);

答案 1 :(得分:1)

在弹性模式中选择全部操作并不复杂,但我会告诉你我们这样做的方式并且效果很好。

我们创建了一个名为“ExList”的List派生控件,它有一个属性“selectAllCB”,我们将它绑定到现有的复选框,该复选框适用于select all逻辑。请注意,当我们设置selectAllCB属性时,我们让ExList听取复选框的事件。

选中复选框后,我们手动将selectedItems数组设置为dataProvider数组,并选择所有项目。

使用itemRenderer无法正常工作,因为每当您必须编写大量代码时,一次又一次地对列表进行编程。

I am attaching some sample code here below..

    public class ExList extends List 
    {
        public function ExTileList()
        {
            super();
            this.allowMultipleSelection = true;
        }

        private var _selectAllCB:CheckBox = null;
        [Bindable]
        public function get selectAllCB():CheckBox
        {
            return _selectAllCB;
        }
        public function set selectAllCB(v:CheckBox):void
        {
            if(v==null)
                return;
            _selectAllCB = v;
            v.addEventListener(ListEvent.ITEM_CLICK, handleAllChange,false, 0 , true);
            v.addEventListener("change", handleAllChange,false, 0 , true);
        }

        private function handleAllChange(e:Event):void
        {
            if(_selectAllCB.selected)
            {
                this.selectedItems = this.dataProvider.toArray();
            }
            else
            {
                this.selectedItems = new Array();
            }
        }
}

你可以用它......

<CheckBox id="sAll"/>
<ExList selectAllCB="{sAll}"/>

// Please note its in curly braces

答案 2 :(得分:0)

这就是我实现解决方案的方式:

    <?xml version="1.0" encoding="utf-8"?>
<mx:VBox xmlns:mx="http://www.adobe.com/2006/mxml" height="150" verticalGap="0">
    <mx:Script>
 <![CDATA[
         import mx.events.ListEvent;
  import mx.controls.CheckBox;
  import mx.collections.ArrayCollection;

  public var listData:ArrayCollection;

  private function selectAll():void
  {
   listChkBox.selectedItems = listData.toArray();
   for each (var item:Object in listChkBox.selectedItems)
   {
    CheckBox(listChkBox.itemToItemRenderer(item)).selected = true;
          }   
  }

  private function resetAll():void
  {
   listChkBox.selectedItems = listData.toArray();
   for each (var item:Object in listChkBox.selectedItems)
   { 
                         CheckBox(listChkBox.itemToItemRenderer(item)).selected = false;
   } 
  }


  ]]>
 </mx:Script>
 <mx:List width="100%" height="100%" id="listChkBox" labelField="name" allowMultipleSelection="true"
   dataProvider="{listData}"  selectionColor="#FFFFFF" >
  <mx:itemRenderer>
   <mx:Component>
    <mx:CheckBox >
    </mx:CheckBox>
   </mx:Component>
  </mx:itemRenderer>
 </mx:List>
 <mx:HBox width="100%"  backgroundColor="#E2DEDE" paddingBottom="2" paddingLeft="2" paddingTop="2" paddingRight="2" borderStyle="solid">
  <mx:Button label="All"  id="btnAll" click="selectAll()" />
  <mx:Button label="None" click="resetAll()"/>
 </mx:HBox>
</mx:VBox>

答案 3 :(得分:0)

简单的解决方案是在您呈现的数据列表中使用类型化对象,然后利用数据绑定和绑定工具来捕获对项呈示器的基础数据属性的更改。覆盖项呈示器中的“设置数据”功能,以便在对象中的某个属性发生更改时执行所需操作,以反映“全选/全选全部”状态。