This fix Changes the CheckBox renderer from an editor to an inline renderer and updates the dataProvider item on click, and calls itemUpdated() on the dataProvider.
CBODisableIR.mxml (using Object as the item, and fixing the call to super.commitProperties per Alex.) <?xml version="1.0" encoding="utf-8"?> <mx:ComboBox xmlns:mx="http://www.adobe.com/2006/mxml" initialize="init()" > <mx:Script><![CDATA[ import mx.controls.DataGrid; import mx.collections.ArrayCollection; private var _oItem:Object; private function init():void { this.dataProvider = new ArrayCollection(["AAAA","bbbb","cccc","dddd"]); }//init override public function set data(value:Object):void { super.data = value; _oItem = value; invalidateProperties(); }//set data override protected function commitProperties():void { if (_oItem) { //this.enabled = !([EMAIL PROTECTED] == "true"); //XML this.enabled = !_oItem.disabledFlag; //Object } super.commitProperties(); }//commitProperties ]]></mx:Script> </mx:ComboBox> CBODisable.mxml: <?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical" horizontalAlign="left" creationComplete="init()"> <mx:Script><![CDATA[ import mx.collections.XMLListCollection; import mx.collections.ArrayCollection; import CBODisableIR; [Bindable]public var _acMainDP1:ArrayCollection = new ArrayCollection(); [Bindable]private var _xmlMainDP1:XML; private function init():void { buildMainDp(); } private function buildMainDp():void { _acMainDP1.addItem({value:"C", disabledFlag: false}); _acMainDP1.addItem({value:"2", disabledFlag: true}); _acMainDP1.addItem({value:"BLUE", disabledFlag: false}); _xmlMainDP1 = <data> <item value="C" disabledFlag="false" /> <item value="2" disabledFlag="true" /> <item value="Blue" disabledFlag="false" /> </data> }//buildMainDp ]]></mx:Script> <mx:DataGrid id="dg1" width="300" editable="true" dataProvider="{_acMainDP1}" > <mx:columns> <mx:DataGridColumn headerText="Value" width="60" dataField="value" editable="false" /> <mx:DataGridColumn headerText="Disable Combo" width="60" headerWordWrap="true" paddingLeft="10" editable="false" > <mx:itemRenderer> <mx:Component> <mx:CheckBox selected="{data.disabledFlag}" click="data.disabledFlag=selected; outerDocument._acMainDP1.itemUpdated(data)" /> </mx:Component> </mx:itemRenderer> </mx:DataGridColumn> <mx:DataGridColumn headerText="CBO Value" dataField="@value" itemRenderer="CBODisableIR" editable="false" /> </mx:columns> </mx:DataGrid> <mx:Button label="invalidateList()" click="{dg1.invalidateList()}" /> </mx:Application> -----Original Message----- From: [email protected] [mailto:[EMAIL PROTECTED] On Behalf Of Tracy Spratt Sent: Thursday, November 29, 2007 6:26 PM To: [email protected] Subject: RE: [flexcomponents] Re: How to call invalidateList()...... ONE SOLUTION In case anyone follows this later, I'll post a few solutions here. This first uses XML for the dataProvider, which is bindable so does not suffer from the limitations of the dynamic object used previously, and changes the CheckBox renderer to update the dataProvider on click, instead of waiting until the edit session ends. REMEMBER, this is just to show disabling the CBO and the CBO does not do anything. CBODisableIR.mxml is the same, except replace commitProperties with this: override protected function commitProperties():void { if (_oItem) { this.enabled = !([EMAIL PROTECTED] == "true"); } super.commitProperties(); }//commitProperties CBODisableTest.mxml: <?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical" horizontalAlign="left" creationComplete="init()"> <mx:Script><![CDATA[ import mx.collections.XMLListCollection; import mx.collections.ArrayCollection; import CBODisableIR; [Bindable]private var _acMainDP1:ArrayCollection = new ArrayCollection(); [Bindable]private var _xmlMainDP1:XML; private function init():void { buildMainDp(); } private function buildMainDp():void { _acMainDP1.addItem({value:"C", disabledFlag: false}); _acMainDP1.addItem({value:"2", disabledFlag: true}); _acMainDP1.addItem({value:"BLUE", disabledFlag: false}); _xmlMainDP1 = <data> <item value="C" disabledFlag="false" /> <item value="2" disabledFlag="true" /> <item value="Blue" disabledFlag="false" /> </data> }//buildMainDp ]]></mx:Script> <mx:DataGrid id="dg1" width="300" editable="true" dataProvider="{_xmlMainDP1.item}" > <mx:columns> <mx:DataGridColumn headerText="Value" width="60" dataField="@value" editable="false" /> <mx:DataGridColumn headerText="Disable Combo" width="60" headerWordWrap="true" paddingLeft="10" editable="false" > <mx:itemRenderer> <mx:Component> <mx:CheckBox click="XML(data)[EMAIL PROTECTED]" selected="{(XML(data)[EMAIL PROTECTED] == 'true')?true:false}"/> </mx:Component> </mx:itemRenderer> </mx:DataGridColumn> <mx:DataGridColumn headerText="CBO Value" dataField="@value" itemRenderer="CBODisableIR" editable="false" /> </mx:columns> </mx:DataGrid> <mx:Button label="invalidateList()" click="{dg1.invalidateList()}" /> </mx:Application> ________________________________________ From: [email protected] [mailto:[EMAIL PROTECTED] On Behalf Of Tracy Spratt Sent: Thursday, November 29, 2007 5:52 PM To: [email protected] Subject: RE: [flexcomponents] Re: How to call invalidateList() from within a renderer Doh!, I'd somenow missed that bit about dynamic objects and itemUpdated, but when I googled my archives I found many times when Alex said: "Unless the data object is [bindable], modifications to data objects must be accompanied by a call to itemUpdated on the collection." And sorry, Ben, of course that dynamic object is not strongly typed like I said. And seeing the update happening was a function of my debugging technique, since usually I was causing the focus to leave the editor. I've got it now, thanks guys. Tracy ________________________________________ From: [email protected] [mailto:[EMAIL PROTECTED] On Behalf Of Alex Harui Sent: Thursday, November 29, 2007 3:31 PM To: [email protected] Subject: RE: [flexcomponents] Re: How to call invalidateList() from within a renderer So the first problem I see is that at startup, none of the Combo's are disabled. That is because Combo disabling is handled in commitProperties and you are changing the enabled after super.commitProperties. That is fixed by moving super.commitProperties: override protected function commitProperties():void { if (_oItem) { var bDisabled:Boolean = !_oItem.disabledFlag this.enabled = bDisabled; trace("commitProperties - value:" + _oItem.value + ", DISABLED=" + (this.enabled == false)); } super.commitProperties(); }//commitProperties The next problem is that clicking a checkbox doesn't update. Editing is session based and won't update the DP on click, but later when focus leaves the editor. Normally you put in a click/change event on the checkbox renderer and call itemUpdated on that event. ________________________________________ From: [email protected] [mailto:[EMAIL PROTECTED] On Behalf Of Tracy Spratt Sent: Thursday, November 29, 2007 12:08 PM To: [email protected] Subject: RE: [flexcomponents] Re: How to call invalidateList() from within a renderer The CBO set data and commitProperties overrides are getting called correctly by the framework whenever I click the checkbox in the other column, and the CBO.enabled property is being set correctly, per the trace. If you have time and inclination, take a look at my test case the other post. Thanks, Tracy -----Original Message----- From: [email protected] [mailto:[EMAIL PROTECTED] On Behalf Of ben.clinkinbeard Sent: Thursday, November 29, 2007 12:55 PM To: [email protected] Subject: [flexcomponents] Re: How to call invalidateList() from within a renderer > I should not, I think, need to call itemUpdated(). What is supposed to cause your ComboBox to revalidate then? I could certainly be wrong but its worth a shot. --- In [email protected], "Tracy Spratt" <[EMAIL PROTECTED]> wrote: > > Yes it is an AC of strongly typed objects, and only certain properties > are marked [Bindable], not the entire class. I think Alex must be right, > I have some other problem. I should not, I think, need to call > itemUpdated(). > > A related question, since I am not depending on binding in the renderer, > but explicitly accessing the public members, should the bindability of > those members be significant? Theoretically, I mean, obviously I have > some problem somewhere. > > Tracy > > > -----Original Message----- > From: [email protected] > [mailto:[EMAIL PROTECTED] On Behalf Of ben.clinkinbeard > Sent: Thursday, November 29, 2007 9:05 AM > To: [email protected] > Subject: [flexcomponents] Re: How to call invalidateList() from within a > renderer > > Hi Tracy, > > Are the items in your dataProvider strongly typed objects whose whole > class is marked [Bindable]? If not, you might try calling > itemUpdated() on your dataProvider (assuming its an ArrayCollection). > > HTH, > Ben > > > > --- In [email protected], "Tracy Spratt" <tspratt@> > wrote: > > > > I want my ComboBox itemRenderer to be disabled based on a > "disabledFlag" > > property in the dataProviderItem. > > > > I have a CheckBox renderer in another column that updates that > property. > > > > The ComboBox renderers display fine on initialize, with the correct > rows > > disabled > > > > But when I click the checkbox, even though the code in the CBO > > renderer's set data() and commitProperties runs correctly and sets the > > Combobox enabled property correctly, the ComboBox interactivity is not > > correct until something redraws the list, like scrolling. > > > > I can make it work with an external button that calls invalidateList() > > on the DataGrid, but I want to do that from within the renderer. I > have > > tried: > > > > /** called from commitProperties */ > > private function setEnabled():void > > { > > this.enabled = !_oItem.disabledFlag; > > DataGrid(_dgListData.owner).invalidateList(); > > }//setEnabled > > > > But this does not seem to do anything. > > > > Where, when and how should I make the invalidateList call from within > my > > renderer? > > > > > > > > Yahoo! Groups Links > Yahoo! Groups Links Yahoo! Groups Links
