Создание столбца RadioButtons в Adobe Flex - PullRequest
0 голосов
/ 22 сентября 2008

Я использую виджет AdvancedDataGrid и хочу, чтобы два столбца были переключателями, где каждый столбец - это собственная RadioButtonGroup. Я думал, что у меня есть все необходимые mxxml, но я столкнулся со странной проблемой поведения. Когда я прокручиваю вверх и вниз, кнопка меняет значения! Выбранная кнопка отменяется, а невыбранные становятся выбранными. У кого-нибудь есть подсказка об этой ошибке? Должен ли я идти об этом по-другому. - Вот урезанный пример того, что я пытаюсь сделать.

<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
  <mx:RadioButtonGroup id="leftAxisGrp" />
  <mx:RadioButtonGroup id="rightAxisGrp">
    <mx:change>
      <![CDATA[
        trace (rightAxisGrp.selection);
        trace (rightAxisGrp.selection.data.name);
      ]]>
    </mx:change>
  </mx:RadioButtonGroup>
  <mx:AdvancedDataGrid
      id="readingsGrid"
      designViewDataType="flat"
      height="150" width="400"
      sortExpertMode="true"
      selectable="false">
    <mx:columns>
      <mx:AdvancedDataGridColumn
          headerText="L" width="25" paddingLeft="6"
          dataField="left" sortable="false">
        <mx:itemRenderer>
          <mx:Component>
            <mx:RadioButton groupName="leftAxisGrp" />
          </mx:Component>
        </mx:itemRenderer>
      </mx:AdvancedDataGridColumn>
      <mx:AdvancedDataGridColumn
          headerText="R" width="25" paddingLeft="6"
          dataField="right" sortable="false">
        <mx:itemRenderer>
          <mx:Component>
            <mx:RadioButton groupName="rightAxisGrp" />
          </mx:Component>
        </mx:itemRenderer>
      </mx:AdvancedDataGridColumn>
      <mx:AdvancedDataGridColumn headerText="" dataField="name" />
    </mx:columns>
    <mx:dataProvider>
      <mx:Array>
        <mx:Object left="false" right="false" name="Reddish-gray Mouse Lemur" />
        <mx:Object left="false" right="false" name="Golden-brown Mouse Lemur" />
        <mx:Object left="false" right="false" name="Northern Rufous Mouse Lemur" />
        <mx:Object left="false" right="false" name="Sambirano Mouse Lemur" />
        <mx:Object left="false" right="false" name="Simmons' Mouse Lemur" />
        <mx:Object left="false" right="false" name="Pygmy Mouse Lemur" />
        <mx:Object left="false" right="false" name="Brown Mouse Lemur" />
        <mx:Object left="false" right="false" name="Madame Berthe's Mouse Lemur" />
        <mx:Object left="false" right="false" name="Goodman's Mouse Lemur" />
        <mx:Object left="false" right="false" name="Jolly's Mouse Lemur" />
        <mx:Object left="false" right="false" name="Mittermeier's Mouse Lemur" />
        <mx:Object left="false" right="false" name="Claire's Mouse Lemur" />
        <mx:Object left="false" right="false" name="Danfoss' Mouse Lemur" />
        <mx:Object left="false" right="false" name="Lokobe Mouse Lemur" />
        <mx:Object left="true" right="true" name="Bongolava Mouse Lemur" />
      </mx:Array>
    </mx:dataProvider>
  </mx:AdvancedDataGrid>
</mx:WindowedApplication>

ОБНОВЛЕНО (спасибо, счет!)

Хорошо! Иди это работает. Я просто должен был сделать пару изменений по предложению Билла. Главным образом используя ArrayCollection с ObjectProxy, чтобы он был привязываемым и динамическим. Одна странная вещь - я не мог выбрать кнопку в первом ряду, если я заполнил массив во время построения; Я должен был отложить это до тех пор, пока не было инициировано событие creationComplete (что нормально, так как я собираюсь заполнить сетку из БД в любом случае).

<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
  <mx:Script>
    <![CDATA[
      import mx.utils.ObjectProxy;
      import mx.collections.ArrayCollection;

      [Bindable]
      private var myData:ArrayCollection = new ArrayCollection ();

      private function selectItem (selObject:Object, property:String) : void
      {
        for each (var obj:ObjectProxy in myData) {
          obj[property] = (obj.name === selObject.name);
        }
        readingsGrid.invalidateDisplayList ();
      }
    ]]>
  </mx:Script>
  <mx:RadioButtonGroup id="leftAxisGrp">
    <mx:change>
      <![CDATA[
        selectItem (leftAxisGrp.selectedValue, 'left');
      ]]>
    </mx:change>
  </mx:RadioButtonGroup>
  <mx:RadioButtonGroup id="rightAxisGrp">
    <mx:change>
      <![CDATA[
        selectItem (rightAxisGrp.selectedValue, 'right');
      ]]>
    </mx:change>
  </mx:RadioButtonGroup>
  <mx:AdvancedDataGrid
      id="readingsGrid"
      designViewDataType="flat"
      dataProvider="{myData}"
      sortExpertMode="true"
      height="150" width="400"
      selectable="false">
    <mx:columns>
      <mx:AdvancedDataGridColumn id="leftCol"
          headerText="L" width="25" paddingLeft="6" sortable="false">
        <mx:itemRenderer>
          <mx:Component>
            <mx:RadioButton groupName="leftAxisGrp"
                buttonMode="true" value="{data}" selected="{data.left}" />
          </mx:Component>
        </mx:itemRenderer>
      </mx:AdvancedDataGridColumn>
      <mx:AdvancedDataGridColumn id="rightCol"
          headerText="R" width="25" paddingLeft="6" sortable="false">
        <mx:itemRenderer>
          <mx:Component>
            <mx:RadioButton groupName="rightAxisGrp"
                buttonMode="true" value="{data}" selected="{data.right}" />
          </mx:Component>
        </mx:itemRenderer>
      </mx:AdvancedDataGridColumn>
      <mx:AdvancedDataGridColumn headerText="" dataField="name" />
    </mx:columns>
    <mx:creationComplete>
      <![CDATA[
      myData.addItem(new ObjectProxy ({ left:true, right:true, name:"Golden-brown Mouse Lemur" }));
      myData.addItem(new ObjectProxy ({ left:false, right:false, name:"Reddish-gray Mouse Lemur" }));
      myData.addItem(   new ObjectProxy ({ left:false, right:false, name:"Northern Rufous Mouse Lemur" }));
      myData.addItem(   new ObjectProxy ({ left:false, right:false, name:"Sambirano Mouse Lemur" }));
      myData.addItem(   new ObjectProxy ({ left:false, right:false, name:"Simmons' Mouse Lemur" }));
      myData.addItem(   new ObjectProxy ({ left:false, right:false, name:"Pygmy Mouse Lemur" }));
      myData.addItem(   new ObjectProxy ({ left:false, right:false, name:"Brown Mouse Lemur" }));
      myData.addItem(   new ObjectProxy ({ left:false, right:false, name:"Madame Berthe's Mouse Lemur" }));
      myData.addItem(   new ObjectProxy ({ left:false, right:false, name:"Goodman's Mouse Lemur" }));
      myData.addItem(   new ObjectProxy ({ left:false, right:false, name:"Jolly's Mouse Lemur" }));
      myData.addItem(   new ObjectProxy ({ left:false, right:false, name:"Mittermeier's Mouse Lemur" }));
      myData.addItem(   new ObjectProxy ({ left:false, right:false, name:"Claire's Mouse Lemur" }));
      myData.addItem(   new ObjectProxy ({ left:false, right:false, name:"Danfoss' Mouse Lemur" }));
      myData.addItem(   new ObjectProxy ({ left:false, right:false, name:"Lokobe Mouse Lemur" }));
      myData.addItem(   new ObjectProxy ({ left:false, right:false, name:"Bongolava Mouse Lemur" }));               
      ]]>
    </mx:creationComplete>
  </mx:AdvancedDataGrid>
</mx:WindowedApplication>

Ответы [ 2 ]

1 голос
/ 22 сентября 2008

Здесь происходит то, что Flex создает экземпляры itemRenderer только для видимых столбцов. Когда вы прокручиваете, эти экземпляры перерабатываются. Так что, если вы прокрутите вниз, объект RadioButton, который рисовал первый столбец первой строки, теперь мог бы измениться на рисунок первого столбца седьмой строки. Flex сбрасывает свойство data в itemRenderer, когда это происходит.

Таким образом, хотя имеется 15 строк данных, всегда есть только 12 RadioButton (6 для «левого» и 6 «для правого» для 6 видимых строк), а не 30 RadioButton, как вы могли бы ожидать. Это не большая проблема, если вы только отображаете выбор, но это становится большей проблемой, когда вы разрешаете обновления.

Чтобы устранить проблему с отображением, вместо установки «dataField» в столбце, вы можете привязать свойство «selected» RadioButton к значению dataRlederer data.left (или right). Затем вам нужно будет сделать элементы в вашем dataProvider "Bindable".

Чтобы устранить проблему с обновлением, поскольку вы будете привязываться непосредственно к значениям элемента dataProvider, вам необходимо обязательно обновить их. Поскольку для каждого элемента нет RadioButton, вам понадобится другая схема для этого. В этом случае я помещаю обработчик, который идет и устанавливает свойство left / right каждого элемента в «false», за исключением «selected», которому присваивается значение «true».

Я обновил ваш пример кода на основе этих мыслей. Попробуйте что-то вроде этого:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application  layout="absolute"
    xmlns:my="*"
    xmlns:mx="http://www.adobe.com/2006/mxml">
  <mx:RadioButtonGroup id="leftAxisGrp"
       change="selectItem(leftAxisGrp.selectedValue, 'left');"/>
  <mx:RadioButtonGroup id="rightAxisGrp"
       change="selectItem(rightAxisGrp.selectedValue, 'right');">
  </mx:RadioButtonGroup>
  <mx:AdvancedDataGrid
      id="readingsGrid"
      designViewDataType="flat"
      height="150" width="400"
      sortExpertMode="true"
      selectable="false"
      dataProvider="{adgData.object}">
    <mx:columns>
      <mx:AdvancedDataGridColumn
          headerText="L" width="25" paddingLeft="6"
          sortable="false">
        <mx:itemRenderer>
          <mx:Component>
            <mx:RadioButton groupName="leftAxisGrp" 
                value="{data}" selected="{data.left}"/>
          </mx:Component>
        </mx:itemRenderer>
      </mx:AdvancedDataGridColumn>
      <mx:AdvancedDataGridColumn
          headerText="R" width="25" paddingLeft="6"
          sortable="false">
        <mx:itemRenderer>
          <mx:Component>
            <mx:RadioButton groupName="rightAxisGrp"
                value="{data}" selected="{data.right}"/>
          </mx:Component>
        </mx:itemRenderer>
      </mx:AdvancedDataGridColumn>
      <mx:AdvancedDataGridColumn headerText="" dataField="name" />
    </mx:columns>
  </mx:AdvancedDataGrid>
  <mx:Model id="adgData">
      <root>
        <object left="false" right="false" name="Reddish-gray Mouse Lemur" />
        <object left="false" right="false" name="Golden-brown Mouse Lemur" />
        <object left="false" right="false" name="Northern Rufous Mouse Lemur" />
        <object left="false" right="false" name="Sambirano Mouse Lemur" />
        <object left="false" right="false" name="Simmons' Mouse Lemur" />
        <object left="false" right="false" name="Pygmy Mouse Lemur" />
        <object left="false" right="false" name="Brown Mouse Lemur" />
        <object left="false" right="false" name="Madame Berthe's Mouse Lemur" />
        <object left="false" right="false" name="Goodman's Mouse Lemur" />
        <object left="false" right="false" name="Jolly's Mouse Lemur" />
        <object left="false" right="false" name="Mittermeier's Mouse Lemur" />
        <object left="false" right="false" name="Claire's Mouse Lemur" />
        <object left="false" right="false" name="Danfoss' Mouse Lemur" />
        <object left="false" right="false" name="Lokobe Mouse Lemur" />
        <object left="true" right="true" name="Bongolava Mouse Lemur" />
      </root>
  </mx:Model>
  <mx:Script>
    <![CDATA[
        private function selectItem(selObject:Object, property:String) : void {
            for each(var obj:Object in adgData.object) {
                obj[property] = (obj === selObject);
            }
            readingsGrid.invalidateDisplayList();
        }
    ]]>
  </mx:Script>
</mx:Application>
0 голосов
/ 22 сентября 2008

Воспроизведено это. Скорее всего, это ошибка ADG, мы столкнулись с некоторыми здесь. (Не нашел этого на bugs.adobe.com, но их поиск - отстой).

Вы можете попробовать Flex 3.0.3 или ночную сборку здесь (предупреждение, может быть, довольно сильно сломано), и посмотреть, исправили ли они это, или вы можете попробовать реализовать собственный рендер, но это боль, чтобы получить право.

...