Flex3: средство визуализации пользовательских элементов не прослушивает события, отправленные родителем - PullRequest
1 голос
/ 23 апреля 2009

У меня есть список с пользовательским 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 ]

2 голосов
/ 23 апреля 2009

Ваши пользовательские ItemRenderers не должны регистрировать прослушиватель событий со своим родителем, но с вашим флажком «выбрать все», т.е.

theCheckbox.addEventListener(YourEvent.YOUR_EVENT, itemRendererSelectAllHandler);

Если это не удастся, вы можете опубликовать свой код, который добавляет прослушиватель событий и который отправляет событие из флажка?

редактирование:

Вот ваша ошибка: в init () рендерера вам нужно добавить слушатель события не в рендерер, а в контейнер, который отправляет событие. Так что сделайте это

container.addEventListener(Container.SELECT_ALL_USERS, selectAllHandler, false, 0, true);
1 голос
/ 23 апреля 2009

Делать select all на flex немного сложнее, но я расскажу вам, как мы это сделали, и это прекрасно работает.

Мы создали производный элемент управления List с именем «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
0 голосов
/ 22 декабря 2010

Простое решение состоит в том, чтобы использовать типизированные объекты в списке данных, которые вы представляете, а затем использовать привязку данных и привязку, чтобы фиксировать изменения в базовом свойстве данных в средстве визуализации элементов. Переопределите функцию 'set data' в средстве визуализации элементов, чтобы делать все, что вам нужно, когда какое-либо свойство в объекте изменяется, отражая состояние 'select all / de select all'.

0 голосов
/ 08 января 2010

Вот как я добился решения:

    <?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>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...