1

我有一个带有自定义 ItemRenderer 的列表。ItemRenderer 包含一个复选框和一个标签。带有列表的组件有一个“全选”复选框。当“全选”复选框被选中时,它会调度一个事件,每个项目都应该监听以选择自己的复选框。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

4 回答 4

2

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

theCheckbox.addEventListener(YourEvent.YOUR_EVENT, itemRendererSelectAllHandler);

如果做不到这一点,您可以发布添加事件侦听器并从复选框分派事件的代码吗?

编辑:

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

container.addEventListener(Container.SELECT_ALL_USERS, selectAllHandler, false, 0, true);
于 2009-04-23T09:37:57.620 回答
1

在 flex 中进行全选并不复杂,但我会告诉你我们是如何做到的,而且效果很好。

我们创建了一个名为“ExList”的列表派生控件,它具有一个属性“selectAllCB”,我们将其绑定到现有的复选框,该复选框将适用于选择所有逻辑。请注意,当我们设置 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
于 2009-04-23T09:51:02.313 回答
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>
于 2010-01-08T02:23:19.720 回答
0

简单的解决方案是在您呈现的数据列表中使用类型化对象,然后利用数据绑定和绑定实用程序来捕获对项目渲染器上的基础数据属性的更改。当对象中的某些属性被更改以反映“全选/全选”状态时,覆盖项目渲染器中的“设置数据”功能以执行您需要的任何操作。

于 2010-12-22T16:14:06.233 回答