DataGrid itemrender - apache-flex

Hi i have added a control with the help itemrender in my datagrid. but there is a problem that
in time of execution it comes two times at init and creation complete event of that control
which i added in my datagrid column.
Thanks
Atul Yadav
<?xml version="1.0" encoding="utf-8"?>
<mx:DataGridColumn xmlns:mx="http://www.adobe.com/2006/mxml" xmlns:ns1="Component.*" >
<mx:Script>
<![CDATA[
[Bindable]
public var columnID:String="";
[Bindable]
public var ColumnData:String="";
]]>
</mx:Script>
<mx:itemRenderer>
<mx:Component>
<ns1:test >
</ns1:test>
</mx:Component>
</mx:itemRenderer>
</mx:DataGridColumn>
and my control code:
<?xml version="1.0" encoding="utf-8"?>
<mx:VBox xmlns:mx="http://www.adobe.com/2006/mxml" width="400" height="300" xmlns:ns1="View.*" creationComplete="init(event)">
<mx:Script>
<![CDATA[
import mx.controls.Alert;
private static var arr:Array;
private function init(e:Event):void{
if(!arr)
arr=new Array();
arr.push(this);
btn_apply.addEventListener(MouseEvent.CLICK,function(e:Event):void{Alert.show(arr.length.toString());});
}
]]>
</mx:Script>
<mx:Button label="Button" id="btn_apply"/>
</mx:VBox>
when i get arr length it gives me just double count.

If I understand correctly the second code snippet is your custom item renderer that is instantiated as <ns1:test> in the first snippet.
The DataGrid control will create instances of your renderer as and when it sees fit - you don't really have any control of how many instances will get created. So while you may have one row in the column the Data Grid is quite likely to have created more than one instance of the renderer component. The result, as you can see, is that creation complete is called more than once and you are getting more items in your static array than you are expecting. When developing item renderers you have to take into account that: you don't control their instantiation and that they are recycled by the framework. The best approach to take is to make them as stateless as possible.

Related

Passing a parameter from flex main to a flex(4) component with data binding

I have a main mxml file (flex4) and want to pass a parameter (user_name) to a component in a directory called components.
When I run the program, the user_name is NOT being sent from the main to the component file.
(Interestingly, if you make the component visible, you can see the parameter has been passed)
New to flex/actionscript and this parameter passing is (without help) quite a pain to progress.
So, help would be very much appreciated.
TIA.
I have hacked much larger files down to get the following two files:
MAIN
<?xml version="1.0" encoding="utf-8"?>
<s:Application
xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600"
xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:components="components.*">
<mx:Button id="editAccount" label="Edit Account" fontSize="16" color="#000000" x="100" y="125" click="AccountForm(event)" />
<components:editAccountForm visible="false" user_name = "username from main" />
<fx:Script>
<![CDATA[
import components.editAccountForm;
import mx.managers.PopUpManager;
private function AccountForm(e:MouseEvent):void
{
var win3:editAccountForm = new editAccountForm();
PopUpManager.addPopUp(win3,this,true);
PopUpManager.centerPopUp(win3);
}
]]>
</fx:Script>
</s:Application>
COMPONENT FILE
<?xml version="1.0" encoding="utf-8"?>
<mx:TitleWindow xmlns:mx="http://www.adobe.com/2006/mxml"
layout="vertical" title="Edit Account Details" x="50" y="600" >
<mx:Form width="100%" height="100%">
<mx:FormItem label="">
<mx:Label width="300" textAlign="center" text="{user_name}"/>
</mx:FormItem>
<mx:FormItem label="Enter your new Email Address">
<mx:TextInput id="email_address2" width="300" maxChars="128" contentBackgroundColor="#F5DC0C"/>
</mx:FormItem>
</mx:Form>
<mx:HBox width="100%" horizontalAlign="center">
<mx:Button id="close" label="Close" click="PopUpManager.removePopUp(this)" />
</mx:HBox>
<mx:Script>
<![CDATA[
[Bindable]
public var user_name:String = "username from Component";
]]>
</mx:Script>
<mx:Script>
<![CDATA[
import mx.core.IFlexDisplayObject;
import mx.events.CloseEvent;
import mx.managers.PopUpManager;
private function closeWindow(e:CloseEvent):void
{
PopUpManager.removePopUp(e.target as IFlexDisplayObject);
}
]]>
</mx:Script>
</mx:TitleWindow>
If you simply want to get the user_name from the main app into your TitleWindow component, just set win3.user_name = user_name after you instantiate win3. If you are looking to bind it to your newly instantiated win3 (which you would do if user_name were expected to change), then you need to look into the BindUtils helper class.
The typical way of getting data back and forth between an app and a dialog is to set the value after you instantiate your dialog, and then add a listener to your dialog so that your app will get notified if something changed. If you are listening for the Close event, for example, you can get the value from the event like so: (event.currentTarget as EditAccountForm).user_name in your app's event handler.
Another common method is to have your window dispatch a custom event (that your main app added a listener to the dialog for) which contains the new value for user_name.
Hope that helps.

Binding custom components values

I have built a custom component using some containers and a TileList.
Now when I instantiate that component in my main Flex app, I want to get the value of the selected item in the tileList that the user clicks on. In other words, everytime the user clicks an item in the tileList, I want it to assign that selected value to a global application variable in the main flex app.
Any ideas how to do that?
Below is one way that you can listen to the change of TileList.selectedItem. I would recommend against putting this in a global variable, although if you must you could use a pattern like ModelLocator to do so.
<?xml version="1.0" encoding="utf-8"?>
<mx:Application
xmlns:mx="http://www.adobe.com/2006/mxml"
layout="vertical">
<mx:Script>
<![CDATA[
[Bindable] public var selectedItem:Object;
]]>
</mx:Script>
<mx:Binding source="listTile.selectedItem" destination="selectedItem"/>
<mx:Label text="{ selectedItem }"/>
<mx:TileList
id="listTile"
width="400"
height="300"
dataProvider="{ ['A','B','C'] }"/>
</mx:Application>

Flex: Components bound to empty ArrayCollection at load time don't render as expected when the ArrayCollection is updated

I'm new to Flex and am using TileList bound to an ArrayCollection. The array collection is empty at load time, and then updates with the results from am HTTPService call. The problem is that the item renderers aren't being rendered as expected, I'm guessing because there was no data when they were first rendered at load time. Here's simplified example:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" >
<mx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
[Bindable]
public var myList1:ArrayCollection = new ArrayCollection();
[Bindable]
public var myList2:ArrayCollection = new ArrayCollection([{item:"foo"}, {item:"bar"}]);
public function updateMyList():void
{
myList1.source = [{item:"foo"}, {item:"bar"}];
}
]]>
</mx:Script>
<mx:Button id="myButton" label="Update My List"
click="updateMyList();"/>
<mx:TileList dataProvider="{myList1}"
direction="vertical"
width="800" >
<mx:itemRenderer>
<mx:Component >
<mx:Canvas backgroundColor="yellow" >
<mx:Label text="{data.item}" width="800" />
</mx:Canvas>
</mx:Component>
</mx:itemRenderer>
</mx:TileList>
<!-- This one renders as expected -->
<mx:TileList dataProvider="{myList2}"
direction="vertical"
width="800" >
<mx:itemRenderer>
<mx:Component >
<mx:Canvas backgroundColor="yellow" >
<mx:Label text="{data.item}" width="800" />
</mx:Canvas>
</mx:Component>
</mx:itemRenderer>
</mx:TileList>
</mx:Application>
You will notice that the second TileList whose bindings has data at load time renders as expected (800px wide), bit the first TileList is rendered is not the correct width and has scrollbars around it.
Could anyone explain why this is happening or even provide some work arounds to avoid this?
Regards,
Chris
It's likely that this section is causing the problems:
public function updateMyList():void
{
myList1.source = [{item:"foo"}, {item:"bar"}];
}
From here:
source of data in the ArrayCollection.
The ArrayCollection object does not
represent any changes that you make
directly to the source array. Always
use the ICollectionView or IList
methods to modify the collection.
This property can be used as the
source for data binding. When this
property is modified, it dispatches
the listChanged event.
So I'd probably change the line to:
myList1= new ArrayCollection([{item:"foo"}, {item:"bar"}]);
http://livedocs.adobe.com/flex/3/langref/mx/controls/TileList.html
Check the API.
Set the columnWidth and rowHeight properties like this,
<mx:TileList dataProvider="{myList1}"
direction="vertical"
width="800" columnWidth="800" rowHeight="25">
There is probably a more "proper" way to do it, but that should get you started.

How content dynamically updated in flex

i need your help about below purposes.
problem-1:In php we can easily move one page to another and easily use different type of function from those pages.In flex3 how i can use different type of .mxml pages like php. Please guide me with tutorials.It will really helpful for me.
problem-2: In same page some content dynamically updated its resource by done one task.How can i do that please guide me.
Rather than treating your Flex application as a series of pages, you may want to consider an all-in-one SWF instead. This greatly reduces navigation time, at the cost of a longer initial download. You can switch among different views using tab pages or view stacks. As far as keeping your functions for each page separate, you can do this by implementing each logical "page" as a separate MXML component. Your top-level application MXML would look something like this:
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
xmlns:my="com.mycompany.myapp"
>
<mx:ViewStack id="pageViewStack" width="100%" height="100%">
<my:MyComponent1 width="100%" height="100%"/>
<my:MyComponent2 width="100%" height="100%"/>
</mx:ViewStack>
</mx:Application>
For your second problem I have 2 files
imageResize.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" viewSourceURL="srcview/index.html">
<mx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
private var _imageHolderWidth:Number = 500;
private var _imageHolderHeight:Number = 500;
[Bindable]
private var imageArrayCollection:ArrayCollection = new ArrayCollection();
private function changeSize():void{
this.imageHolder.width = this._imageHolderWidth *(this.widthSlider.value * 0.01);
this.imageHolder.height = this.imageHolder.width;
}
private function addToTileList():void{
var bitmapData : BitmapData = new BitmapData(this.imageHolder.width, this.imageHolder.height );
var m : Matrix = new Matrix();
bitmapData.draw( this.imageHolder, m );
this.imageArrayCollection.addItem({bitmapData: bitmapData, width: this.imageHolder.width, height: this.imageHolder.height});
}
]]>
</mx:Script>
<mx:Image id="imageHolder" source="#Embed('fx.png')" />
<mx:HSlider id="widthSlider" width="400" y="520" maximum="100" value="100" minimum="1" labels="[1%, 50%, 100%]" snapInterval="1" change="{changeSize();}" liveDragging="true" />
<mx:Button label="add to tile" click="{this.addToTileList();}"/>
<mx:TileList x="520" dataProvider="{this.imageArrayCollection}" itemRenderer="TileListRenderer" />
</mx:Application>
second file TileListRenderer.mxml:
<?xml version="1.0" encoding="utf-8"?>
<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml" width="100" height="140">
<mx:Script>
<![CDATA[
import mx.utils.ObjectUtil;
override public function set data(value:Object):void
{
super.data = value;
}
]]>
</mx:Script>
<mx:VBox horizontalAlign="center">
<mx:Image id="thumbHolder" source="{new Bitmap(data.bitmapData)}" maxWidth="100" maxHeight="100" />
<mx:Label text="{data.width}x{data.height}" />
</mx:VBox>
</mx:Canvas>
Because it is easier to see it with working source (right mouse button to see the source):
blog.arnomanders.nl/upload/imageResize/imageResize.html

How can I drag and drop canvases within a Vbox to re-order?

I'm getting up to speed with Flex and I am looking for any example of implementing a drag and drop re-sort within a vbox container. Basically I have a Vbox that contains a number of canvas's that are full width and 35px high. I want to be able to drag and drop them to re-order within the vbox.
Any help is greatly appreciated - thanks,
b
Have you tried using a mx:List - drag and drop support is already built in and very easy to use - i threw together a sample for you using the dimensions you mentioned:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" creationComplete="init()">
<mx:Script>
<![CDATA[
import mx.controls.Alert;
import mx.events.DragEvent;
import mx.collections.ArrayCollection;
[Bindable]
private var _source:ArrayCollection = new ArrayCollection();
private function init():void{
var n:int = 10;
for(var i:int = 0; i < n; i++){ _source.addItem({value:Math.random()}); }
}
private function handleReorder(event:DragEvent):void{
Alert.show("A change was made!");
}
]]>
</mx:Script>
<mx:List dataProvider="{_source}" width="250" height="500" dragMoveEnabled="true"
dragEnabled="true" dropEnabled="true" dragDrop="handleReorder(event)">
<mx:itemRenderer>
<mx:Component>
<mx:Canvas width="100%" height="35">
<mx:Text text="{data.value}" width="100%" height="100%" selectable="false" />
</mx:Canvas>
</mx:Component>
</mx:itemRenderer>
</mx:List>
</mx:Application>
And there is of course more info here: http://livedocs.adobe.com/flex/3/langref/mx/controls/List.html
good luck!
If I were you, I'd first check the Flex documentation available online. There's this example. You will have to customize this for your list control's itemeditor. There's another example which you should take a look at. If you have a problem let us know.

Resources