meaning - flex ropa
Crear una columna de RadioButtons en Adobe Flex (2)
Estoy usando el widget AdvancedDataGrid y quiero que dos columnas sean botones de radio, donde cada columna es su propio RadioButtonGroup. Pensé que tenía todo el mxxml necesario, pero me encuentro con un problema de comportamiento extraño. Cuando me desplazo hacia arriba y hacia abajo, ¡el botón cambia los valores! El botón seleccionado se deselecciona y los seleccionados se seleccionan. Alguien tiene una pista sobre este error? ¿Debo ir sobre esto de otra manera? - Aquí hay un ejemplo simplificado de lo que trato de hacer.
<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>
ACTUALIZADO (¡gracias factura!)
¡Bien! Hazlo funcionar. Solo tuve que hacer un par de cambios de la sugerencia de Bill. Principalmente usando ArrayCollection con ObjectProxy, por lo que era enlazable y dinámico. Una cosa rara: no pude seleccionar un botón en la primera fila si llené la matriz en el momento de la construcción; Tuve que retrasar eso hasta que se disparó el evento creationComplete (que está bien, ya que voy a llenar la cuadrícula de un db de todos modos).
<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>
Lo que sucede aquí es que Flex solo crea instancias itemRenderer para las columnas visibles . Cuando te desplazas, esas instancias se reciclan. Por lo tanto, si se desplaza hacia abajo, el objeto RadioButton que estaba dibujando la primera columna de la primera fila ahora puede haber cambiado para dibujar la primera columna de la séptima fila. Flex restablece la propiedad "data" del itemRenderer siempre que esto sucede.
Entonces, aunque hay 15 filas de datos, solo hay 12 RadioButtons (6 para la "izquierda" y 6 para la "derecha" para las 6 filas visibles), no 30 RadioButtons, como era de esperar. Esto no es un gran problema si solo está mostrando la selección, pero se convierte en un problema cuando permite actualizaciones.
Para solucionar el problema de visualización, en lugar de establecer el "campo de datos" en la columna, puede vincular la propiedad "seleccionada" de RadioButton con el valor data.left (o derecha) de itemRenderer. A continuación, deberá hacer que los elementos en su proveedor de datos sean "vinculables".
Para solucionar el problema de la actualización, ya que sería vinculante directamente a los valores del elemento del proveedor de datos, debe asegurarse de actualizarlos. Como no hay un RadioButton por artículo, necesitará otro esquema para eso. En este caso, puse un controlador que va y establece la propiedad izquierda / derecha de cada elemento en "falso", excepto el "seleccionado", que se establece en "verdadero".
Actualicé tu código de ejemplo en base a estos pensamientos. Pruebe algo como esto:
<?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>
Reproducido esto Probablemente sea un error de ADG, nos hemos encontrado con algunos aquí. (No encontré este en bugs.adobe.com, pero su búsqueda apesta).
Podrías probar Flex 3.0.3, o una versión nocturna aquí (advertencia, puede estar bastante roto), y ver si lo han arreglado, o podrías intentar implementar un renderizador personalizado, pero es difícil solucionarlo.