Many thanks for the help. I incorporated your suggestions and {poof} the error
messages went away and everything else behaved as it did before.
As for the "exercise for the reader", I'd appreciate some more help. I think I
caught the focusOut event OK, but the code I've tried to update the renderer
with doesn't work right.
--- In [email protected], "valdhor" <valdhorli...@...> wrote:
>
> The problem is to do with item renderers and item editors. The data
> passed to these components is in the form of an Object. The Object class
> does not implement an IEventDispatcher.
>
> So, why does it think you need an IEventDispatcher? Well, to get an
> expression to evaluate in MXML you need to use the squiggly braces. This
> is also known as a binding expression. In both the item renderer and
> item editor there are binding expressions for data.City and data.State.
> data is of type Object so you get an error if you bind to it.
>
> So, how do you fix it? By creating custom item editors and renderers
> that don't rely on data binding. Here is the example rewritten that
> way...
>
> Application:
> <?xml version="1.0" encoding="utf-8"?>
> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
> layout="absolute" width="700">
> <mx:Script>
> <![CDATA[
> import mx.events.DataGridEvent;
> import mx.events.DataGridEventReason;
> import mx.collections.ArrayCollection;
> import Renderers.CityStateEditor;
>
> [Bindable] public var initDG:ArrayCollection = new
> ArrayCollection([
> {Company: 'Acme', Contact: 'Bob Jones',
> Phone: '413-555-1212', City: 'Boston', State: 'MA'},
> {Company: 'Allied', Contact: 'Jane Smith',
> Phone: '617-555-3434', City: 'SanFrancisco', State: 'CA'}
> ]);
>
> // Define the event listener.
> public function processData(event:DataGridEvent):void
> {
> // Check the reason for the event.
> if (event.reason == DataGridEventReason.CANCELLED)
> {
> // Do not update cell.
> //return;
> }
> if(event.dataField == "City and State")
> {
> // Disable copying data back to the control.
> event.preventDefault();
>
> // Get new city from editor.
> myGrid.editedItemRenderer.data.City =
> CityStateEditor(DataGrid(event.target).itemEditorInstance).setCity.text;
>
> // Get new state from editor.
> myGrid.editedItemRenderer.data.State =
> CityStateEditor(DataGrid(event.target).itemEditorInstance).pickState.sel\
> ectedItem;
>
> // Close the cell editor.
> myGrid.destroyItemEditor();
>
> // Notify the list control to update its display.
>
> myGrid.dataProvider.itemUpdated(event.itemRenderer.data);
> }
> }
> ]]>
> </mx:Script>
> <mx:DataGrid id="myGrid" rowHeight="75" dataProvider="{initDG}"
> editable="true" itemEditEnd="processData(event)">
> <mx:columns>
> <mx:DataGridColumn dataField="Company" editable="false"/>
> <mx:DataGridColumn dataField="Contact"/>
> <mx:DataGridColumn dataField="Phone"/>
> <mx:DataGridColumn dataField="City and State" width="150"
> itemEditor="Renderers.CityStateEditor"
> itemRenderer="Renderers.CityStateRenderer"/>
> </mx:columns>
> </mx:DataGrid>
> </mx:Application>
>
> Item Editor (CityStateEditor.mxml):
> <mx:VBox xmlns:mx="http://www.adobe.com/2006/mxml"
> backgroundColor="yellow">
> <mx:Script>
> <![CDATA[
> override public function set data(value:Object):void
> {
> super.data = value;
> if(value != null)
> {
> setCity.text = value.City;
> pickState.selectedItem = value.State;
> }
> }
> ]]>
> </mx:Script>
> <mx:TextInput id="setCity" width="130"/>
> <mx:ComboBox id="pickState">
> <mx:dataProvider>
> <mx:String>AL</mx:String>
> <mx:String>AK</mx:String>
> <mx:String>AR</mx:String>
> <mx:String>CA</mx:String>
> <mx:String>MA</mx:String>
> </mx:dataProvider>
> </mx:ComboBox>
> </mx:VBox>
>
> Item Renderer(CityStateRenderer.mxml):
> <?xml version="1.0" encoding="utf-8"?>
> <mx:Text xmlns:mx="http://www.adobe.com/2006/mxml" width="100%"
> selectable="false">
> <mx:Script>
> <![CDATA[
> override public function set data(value:Object):void
> {
> super.data = value;
> if(value != null)
> {
> text = data.City + ", " + data.State;
> }
> }
> ]]>
> </mx:Script>
> </mx:Text>
>
> Now, as to why the new city does not display if you click on the
> background. This is because the itemEditEnd event does not fire until
> you either type <return> or click on another cell. You are still in the
> item editor when you immediately click on the yellow background. If you
> would like it to update when you click there, you would need to monitor
> the focusOut event of the text input in the item editor. You would then
> need to fire an event off to the application to update the renderers
> data. I will leave that as an exercise for the reader ;-}
>
> --- In [email protected], "mmyszew" <mmyszew@> wrote:
> >
> > If the Flex 3 "Passing multiple values back from an item editor"
> example is run with the debugger, the following messages appear
> repeatedly.
> >
> > warning: unable to bind to property 'State' on class 'Object' (class
> is not an IEventDispatcher)
> > warning: unable to bind to property 'City' on class 'Object' (class is
> not an IEventDispatcher)
> >
> > In addition, If you enter a new city and immediately click the yellow
> background of the city/state cell, the new city doesn't show in the
> renderer. However, the new city is there if you get the editor to
> display again.
> >
> > I'm a relative newbie and would like to use this example as a starting
> point for an application, but I hesitate to start with something that
> looks broken.
> >
> > Your help would be much appreciated.
> >
> > Mat Myszewski
> >
> > Here's the code pasted from the Help files (two files).
> >
> > <mx:VBox xmlns:mx="http://www.adobe.com/2006/mxml"
> > backgroundColor="yellow">
> > <!-- itemRenderers\events\myComponents\CityStateEditor.mxml -->
> >
> > <mx:TextInput id="setCity" width="130" text="{data.City}"/>
> >
> > <mx:ComboBox id="pickState" selectedItem="{data.State}">
> > <mx:dataProvider>
> > <mx:String>AL</mx:String>
> > <mx:String>AK</mx:String>
> > <mx:String>AR</mx:String>
> > <mx:String>CA</mx:String>
> > <mx:String>MA</mx:String>
> > </mx:dataProvider>
> > </mx:ComboBox>
> > </mx:VBox>
> >
> > <?xml version="1.0"?>
> > <!-- itemRenderers\events\ComplexDGEditorReturnObject.mxml -->
> > <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
> > width="700">
> >
> > <mx:Script>
> > <![CDATA[
> >
> > import mx.events.DataGridEvent;
> > import mx.events.DataGridEventReason;
> > import mx.collections.ArrayCollection;
> > import myComponents.CityStateEditor;
> >
> > [Bindable]
> > public var initDG:ArrayCollection = new ArrayCollection([
> > {Company: 'Acme', Contact: 'Bob Jones',
> > Phone: '413-555-1212', City: 'Boston', State:
> 'MA'},
> > {Company: 'Allied', Contact: 'Jane Smith',
> > Phone: '617-555-3434', City: 'SanFrancisco',
> State: 'CA'}
> > ]);
> >
> > // Define the event listener.
> > public function processData(event:DataGridEvent):void {
> > // Check the reason for the event.
> > if (event.reason == DataGridEventReason.CANCELLED){
> > // Do not update cell.
> > return;
> > }
> >
> > if(event.dataField == "City and State")
> > {
> > // Disable copying data back to the control.
> > event.preventDefault();
> >
> > // Get new city from editor.
> > myGrid.editedItemRenderer.data.City =
> CityStateEditor(DataGrid(event.target).itemEditorInstance).setCity.text;
> >
> > // Get new state from editor.
> > myGrid.editedItemRenderer.data.State =
> CityStateEditor(DataGrid(event.target).itemEditorInstance).pickState.sel\
> ectedItem;
> >
> > // Close the cell editor.
> > myGrid.destroyItemEditor();
> >
> > // Notify the list control to update its display.
> >
> myGrid.dataProvider.itemUpdated(event.itemRenderer.data);
> > }
> > }
> > ]]>
> > </mx:Script>
> >
> > <mx:DataGrid id="myGrid"
> > rowHeight="75"
> > dataProvider="{initDG}"
> > editable="true"
> > itemEditEnd="processData(event);">
> > <mx:columns>
> > <mx:DataGridColumn dataField="Company" editable="false"/>
> > <mx:DataGridColumn dataField="Contact"/>
> > <mx:DataGridColumn dataField="Phone"/>
> > <mx:DataGridColumn dataField="City and State" width="150"
> > itemEditor="myComponents.CityStateEditor">
> > <mx:itemRenderer>
> > <mx:Component>
> > <mx:Text selectable="false" width="100%"
> > text="{data.City}, {data.State}"/>
> > </mx:Component>
> > </mx:itemRenderer>
> > </mx:DataGridColumn>
> > </mx:columns>
> > </mx:DataGrid>
> > </mx:Application>
> >
>