代码之家  ›  专栏  ›  技术社区  ›  eduffy

在Adobe Flex中创建一列单选按钮

  •  0
  • eduffy  · 技术社区  · 17 年前

    我正在使用AdvancedDataGrid小部件,我希望两列是单选按钮,其中每列都是自己的RadioButtonGroup。我以为我有了所有必要的MXML,但我遇到了一个奇怪的行为问题。当我上下滚动时,按钮会改变值!选中的按钮将被取消选中,未选中的按钮将被选中。有人知道这个bug的线索吗?我应该换一种方式去做吗?--下面是一个简单的例子,说明我想做什么。

    <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>
    

    更新的 (谢谢比尔!)

    好吧!开始工作吧。我只是对比尔的建议作了一些修改。它主要使用带ObjectProxy的ArrayCollection,因此既可绑定又可动态。有一件奇怪的事情——如果在构建时填充数组,我就无法选择第一行中的按钮;我必须延迟到CreationComplete事件被激发(这很好,因为无论如何我都要从DB填充网格)。

    <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 回复  |  直到 16 年前
        1
  •  1
  •   bill d    17 年前

    这里发生的是flex只为 看得见的 柱。当您滚动时,这些实例将被回收。因此,如果向下滚动,绘制第一行第一列的RadioButton对象现在可能改为绘制第七行的第一列。每当发生这种情况时,flex将重置itemrenderer的“data”属性。

    因此,尽管有15行数据,但只有12个单选按钮(6个表示“左”,6个表示“右”,6个表示“可见行”),而不是您所期望的30个单选按钮。如果你只是 显示 选择,但当您允许更新时,它会成为一个更大的问题。

    要解决显示问题,您可以将RadioButton的“Selected”属性绑定到itemRenderer的data.left(或right)值,而不是在列上设置“DataField”。然后,您需要使数据提供程序中的项“可绑定”。

    要解决更新问题,因为您将直接绑定到数据提供程序项值,所以需要确保更新它们。因为每个项目没有一个单选按钮,所以您需要另一个方案来实现这一点。在本例中,我放入了一个处理程序,该处理程序将每个项的左/右属性设置为“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>
    
        2
  •  0
  •   Simon Buchan    17 年前

    复制了这个。可能是ADG的问题,我们在这里遇到了一些。(在bugs.adobe.com上没有找到这个,但是他们的搜索很糟糕)。

    你可以试试flex 3.0.3,或者一个夜间版本。 here (警告,可能已经很坏了),看看他们是否已经修复了它,或者您可以尝试实现一个自定义的渲染器,但这很难纠正。

    推荐文章