May
2008
In the Flex app that I'm currently working on, I have a DataGrid that uses an itemRenderer to display an image. The image is a 'delete' button that allows the user to delete the item. Fairly straightforward, and the code below was working fine...
<mx:DataGridColumn width="24" sortable="false" paddingLeft="4" paddingRight="4" headerText=""> <mx:itemRenderer> <mx:Component> <mx:Image source="assets/icon_delete.png" horizontalAlign="center" height="17" width="17" click="parentDocument.confirmDelete(event);" /> </mx:Component> </mx:itemRenderer> </mx:DataGridColumn>
... until the customer called and said that the user should not be allowed to delete a record if that record meets a particular condition. OK. I think I can do that. I made some modifications and now had the following code:
<mx:DataGridColumn width="24" sortable="false" paddingLeft="4" paddingRight="4" headerText="" dataField="CAN_DELETE">
<mx:itemRenderer>
<mx:Component>
<mx:Image source="assets/icon_delete.png" horizontalAlign="center" height="17" width="17" click="parentDocument.confirmDelete(event);" visible="{data.CAN_DELETE == 1}" />
</mx:Component>
</mx:itemRenderer>
</mx:DataGridColumn>
I added a "dataField" property to the DataGridColumn, and added a "visible" property to the image itself, bound to the value of CAN_DELETE. Recompiled, and still saw that every record displayed the delete image. I wondered if my logic, as simple as it was, might have been off. just for kicks and giggles, I hard-coded the value "false" into the "visible" property of the image. Still, it displayed for all records. Now this was odd.
One of the big perks of my current job is that i get to work with Tariq Ahmed, Flex guru and all around good guy. While he wasn't able to offer up a reason as to why this behavior was happening, he suggested throwing the image into an <mx:HBox> component. New code:
<mx:DataGridColumn width="24" sortable="false" paddingLeft="4" paddingRight="4" headerText="" dataField="CAN_DELETE">
<mx:itemRenderer>
<mx:Component>
<mx:HBox>
<mx:Image source="assets/icon_delete.png" horizontalAlign="center" height="17" width="17" click="parentDocument.confirmDelete(event);" visible="{data.CAN_DELETE == 1}" />
</mx:HBox>
</mx:Component>
</mx:itemRenderer>
</mx:DataGridColumn>
You'll notice the only change is the addition of the <mx:HBox> around the <mx:Image>. For whatever reason, that worked perfectly. I don't pretend to know why, but I'm curious as heck. Ff you've got any ideas, please feel free to comment and enlighten me.


Comments
Add Comment | Subscribe to Comments
-
-
-
-
-
-
-
Add Comment# Posted Tony Fendall on 5/14/08 1:05 AM
This is only speculation, but I believe that when you are creating an inline item renderer as you are, the <mx:Component> is not actually treated as the item renderer, but the UIComponent within that tag is.
This is means that your image was the item renderer, and the item renderer itself cannot be invisible. The item renderer can be blank, but not invisible. In your second case, the HBox is the item renderer, so the child component can change freely.
There are a few other weird cases which I have come across when using inline item renderers, so as a general rule, I always create item renderers as a seperate class. You then have to replace references to parentDocument with other solutions: http://www.munkiihouse.com/?p=47
# Posted Bryan Bartow on 5/14/08 1:46 AM
As best as I understand the Flex framework (and I admit it's not a whole lot) Tony is right. I guess you could go down the slippery slope of setting the image source dynamically to a transparent png or swf if you really wanted to stick with only the Image component. Making the image a child is much easier however.
# Posted pehching on 7/29/08 2:01 PM
Actually, weirdly enough, i had the exact same problem as you. A datagrid with a column that had a tiny trashcan icon for delete. The icon could only appear when the line/record meeted certain conditions. If i hard coded the visible property, it would always wrongly show up, BUT if i added a creationComplete function to the image tag and inside that function, i put the required condition it would work.
This is my itemrenderer:
<mx:Image xmlns:mx="http://www.adobe.com/2006/mxml" creationComplete="init()" buttonMode="true" width="20" height="20" source="assets/lixo1.png">
<mx:Script>
<![CDATA[
private function init():void
{
if(data.posicao!="---"){
this.visible = false;
}
}
]]>
</mx:Script>
</mx:Image>
Why? I dont know, but its not as tony said that an itemrenderer cannot be invisible, because, with the above example, you can make it invisible. Although i have to admit that what tony said makes sense. :-) The above example is wrong on a different matter, it doesnt allow the itemrenderer to be updated when the datagrid dataprovider is. Adding the condition to the visible property right on the image tag works for the updates, at least as far as i tested.
With Hbox, the condition in the visible property works great. :-)
Thanks for the tip, it seems to have solved one of my problems.
# Posted Monica on 2/19/09 8:17 PM
Thanks for this posting. It helped me figure out an issue for which I couldn't seem to find the info I needed anywhere else.
# Posted Pawe? on 7/16/09 12:26 AM
Thank you for this post. I couldn't find the right solution for a long time.
# Posted narmee on 10/7/09 3:27 AM
Hi,
thanks for the post. Its great help.
I need to compare two values in it...
i.e. visible="{var >= 20}"
but it gives error, that '>' or '<' char is not allowed. Can anyone help me out here
# Posted Mathieu St-Gelais on 1/28/10 12:47 PM
I had a very similar problem, but inside a regular panel. So instead of doing the following in AS:
if(someObject == null) {
imageIcon.visible = false;
}
else {
imageIcon.visible = false;
}
I declared a private [Bindable] variable and the visible property is now bound to it.
[Bindable] private var _iconVisible:Boolean = false;
if(someObject == null) {
_iconVisible = false;
}
else {
_iconVisible = false;
}
My image, declared in MNML:
<mx:Image id="imageIcon" height="24" width="24" source="[...]" visible="{_iconVisible }"/>
I hope this will help someone.