2
votes

In Flex 3, it used to be possible to bind a component property within an itemRenderer via outerDocument. So for instance, if there was a image inside an itemRenderer that was only displayed on a given condition of the parent, something like this would work perfectly:

<mx:itemRenderer>
 <mx:Component>
   <mx:Label text="{data}"/>
   <mx:Image id="img" visible="{outerDocument.ShowImage}" includeInLayout="{outerDocument.ShowImage}"/>
</mx:Component>
</mx:itemRenderer>

where the outer document (not the list, but the mxml the list is in) contained something like

[Bindable]
public function get ShowImage():void
{
return showImage;
}
public function set ShowImage(val:Boolean):void
{
showImage = val;
}

I've tried to do the same thing in Flex 4.5 using Spark item renderers using parentDocument, but it doesn't seem to be aware to the binding. When I do this in Flex 4.5, the itemRenderer doesn't seem to be aware when the parentDocument ShowImage changes.

Has anyone seen this issue and is able to offer a solution?

EDIT: Add Spark Source As requested here is my spark source:

MyItemRenderer.mxml

<s:ItemRenderer xmlns:fx="http://ns.adobe.com/mxml/2009" 
                xmlns:s="library://ns.adobe.com/flex/spark" 
                xmlns:mx="library://ns.adobe.com/flex/mx">
<s:Label id="myLabel" text="{data}/>
<s:Image src="something.png" visible="{parentDocument.ShowImage}" includeInLayout="{parentDocument.ShowImage}"/>
</s:ItemRenderer>

RendererContainer.mxml

<s:Panel xmlns:fx="http://ns.adobe.com/mxml/2009" 
         xmlns:s="library://ns.adobe.com/flex/spark" 
         xmlns:mx="library://ns.adobe.com/flex/mx">
<fx:Script>
<![CDATA[

private var showImage:Boolean = false;

[Bindable]
public function set ShowImage(val:Boolean):void
{
     showImage = val;
}
public function get ShowImage():Boolean
{
     return showImage;
}
]]>
    </fx:Script>
    <!-- Content Group -->
    <s:List id="lstCell" width="100%" height="100%" itemRenderer="MyItemRenderer">      
    </s:List>
</s:Panel>

Ok so there is a checkbox in a wrapper outside of RendererContainer.mxml that dispatches a custom event that is handled by changing a Bindable Boolean. The change in that var then changes the ShowImage property on my RendererContainer component. I would expect that the binding would then be picked up by MyItemRenderer but it doesnt seem to be working.

So my outer wrapper would access ShowImage like this

<comp:RendererContainer id="myId" ShowImage="{myCheckbox.selected}"/>
4
Show the code for the 4.5 example.J_A_X
Normally to make something Bindable you need to specify an event in the Bindable Metadata tag and dispatch that event from the set method. That said are you getting errors? OR the value in the itemRenderer just isn't changing?JeffryHouser
No errors. The itemRenderer just isnt updating. Basically, I have a "control panel" that contains options for what can be displayed within the itemRenderer. The control panel just has a checkbox that dispatches an event when the value changes. The handler for that event updates the property ShowImage(which is marked Bindable) but when I toggle the checkbox, I'm simply not seeing the images appear or disappear in the itemrenderer. Ill post the code for the 4.5Shawn

4 Answers

1
votes

I think this should do the trick for you, YourTypeHere would be the class of the containing object, make sure the ShowImage property is public and bindable.

<mx:itemRenderer>
     <mx:Component> 
     <mx:Script>
        <![CDATA[ 
            import YourTypeHere;
        ]]>
    </mx:Script>
       <mx:Label text="{data}"/>
       <mx:Image id="img" 
        visible="{YourTypeHere(this.parent.ShowImage)}" 
        includeInLayout="{YourTypeHere(this.parent.ShowImage)}"/>
    </mx:Component>
</mx:itemRenderer>

P.s. please don't name properties with a starting uppercase letter, including getters, consider naming it showImage and your private var to something like _showImage instead :D

1
votes

Your getter seems to have return type as void. Change that to Boolean

[Bindable]
public function get ShowImage():Boolean
{
return showImage;
}
public function set ShowImage(val:Boolean):void
{
showImage = val;
}
1
votes

This will help.

<s:Image src="something.png" visible="{RendererContainer(ListSkin(parentDocument).parentDocument).ShowImage}" includeInLayout="{RendererContainer(ListSkin(parentDocument).parentDocument).ShowImage}"/>
1
votes

Following works perfectly fine:

<?xml version="1.0" encoding="utf-8"?>
<s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009" 
                       xmlns:s="library://ns.adobe.com/flex/spark" 
                       xmlns:mx="library://ns.adobe.com/flex/mx">
    <s:layout>
        <s:VerticalLayout/>
    </s:layout>
    <fx:Script>
        <![CDATA[
            import mx.collections.ArrayCollection;
        ]]>
    </fx:Script>
    <fx:Declarations>
        <!-- Place non-visual elements (e.g., services, value objects) here -->
    </fx:Declarations>
    <s:Panel xmlns:fx="http://ns.adobe.com/mxml/2009" 
             xmlns:s="library://ns.adobe.com/flex/spark" 
             xmlns:mx="library://ns.adobe.com/flex/mx">
        <s:layout>
            <s:VerticalLayout/>
        </s:layout>
        <fx:Script>
            <![CDATA[

                private var showImage:Boolean = false;

                [Bindable]
                public function set ShowImage(val:Boolean):void
                {
                    showImage = val;
                }
                public function get ShowImage():Boolean
                {
                    return showImage;
                }
            ]]>
        </fx:Script>
        <s:CheckBox label="Select" change="{ShowImage = !ShowImage}"/>
        <!-- Content Group -->
        <s:List id="lstCell" width="100%" height="100%" dataProvider="{new ArrayCollection(['A','B'])}">
            <s:itemRenderer>
                <fx:Component>
                    <s:ItemRenderer xmlns:fx="http://ns.adobe.com/mxml/2009" 
                                    xmlns:s="library://ns.adobe.com/flex/spark" 
                                    xmlns:mx="library://ns.adobe.com/flex/mx" 
                                    autoDrawBackground="true">
                        <s:layout>
                            <s:HorizontalLayout/>
                        </s:layout>
                        <s:Label id="myLabel" text="{data}"/>
                        <s:Button label="something.png" visible="{outerDocument.ShowImage}" includeInLayout="{outerDocument.ShowImage}"/>
                    </s:ItemRenderer>
                </fx:Component>
            </s:itemRenderer>
        </s:List>
    </s:Panel>

</s:WindowedApplication>