In MXML, when I add components to ViewStack and creationPolicy is auto, components are not instantiated until I switch to them. Say, I have the following code:
<mx:ViewStack creationPolicy="auto">
<s:NavigatorContent>
<s:DataGrid id="dg1" width="300"/>
</s:NavigatorContent>
<s:NavigatorContent>
<s:DataGrid id="dg2" width="100"/>
</s:NavigatorContent>
</mx:ViewStack>
How do I replicate this behavior in ActionScript?
The problem is that my DataGrids hold large chunks of data, and thus I don't want them to be created at the same time.
Looks like the ViewStack class has a creationPolicy property on it. Something like this should work
var v:ViewStack = new ViewStack();
v.creationPolicy = "auto";
var t1:NavigatorContent = new NavigatorContent();
t1.addElement(new DataGrid());
v.addElement(t1);
Please try with this one
var v:ViewStack = new ViewStack();
v.creationPolicy = "auto";
var container:SkinnableContainer = new SkinnableContainer();
container.creationPolicy = "none";
var dg:DataGrid = new DataGrid();
container.addElement(dg);
var t1:NavigatorContent = new NavigatorContent();
t1.addElement(container);
v.addElement(t1);
After viewstack_change handler we need to call
container.createDeferredContent() based on which index view you want to see.
For more details Using the createDeferredContent() method
Related
I’m sure it’s something super simple that I’m missing, but I’m having issues removing a VBox that’s inside an s:Tilegroup. I can't get it to delete. For a test, I was able to delete the VBox when I only added to the stage (instead of the s:TileGroup). The code below shows the concept that I’m playing with as well.
I have a button on stage as well as a blank s:TileGroup to start
When you click the button, it dynamically adds a VBox (that holds some text well) to the s:TileGroup
When that VBox is created, I’m also adding an event listener so that when you click the vbox, it can be deleted
<fx:Script>
<![CDATA[
protected function removeVBOX(event:Event):void{
var t:DisplayObject = DisplayObject(event.target);
t.parent.removeChild(t);
}
private function addVbox() : void {
var vbox :VBox = new VBox();
vbox.addEventListener(MouseEvent.CLICK,removeVBOX);
vbox.width = 400;
vbox.height = 500;
vbox.horizontalScrollPolicy = "off";
vbox.verticalScrollPolicy = "off";
vbox.setStyle("backgroundAlpha", 0.39);
vbox.setStyle("backgroundColor", 0x000000);
vbox.setStyle("paddingLeft", "15");
vbox.setStyle("paddingTop", "15");
vbox.setStyle("paddingRight", "15");
vbox.setStyle("paddingBottom", "15");
var sText :RichText = new RichText();
var sText2 :RichText = new RichText();
var sText3 :RichText = new RichText();
sText.text = "Hello 1";
sText2.text = "Hello 2";
sText3.text = "Hello 3";
//addElement(vbox);
table.addElement(vbox);
vbox.addElement(sText);
vbox.addElement(sText2);
vbox.addElement(sText3);
}
]]>
</fx:Script>
<s:Button x="743" y="767" label="Button" click="addVbox()"/>
<s:TileGroup id="table" x="152" y="81" width="627" height="650" horizontalAlign="center" horizontalGap="13"
orientation="columns" requestedColumnCount="1" verticalAlign="middle" verticalGap="13" >
</s:TileGroup>
Looking at your code, I see that you're adding your VBox to the TileGroup as follows:
table.addElement(vbox);
But then you're trying to remove it using removeChild():
t.parent.removeChild(t);
The proper method to add/remove items to/from Spark containers is add/removeElement():
var t:IVisualElement = IVisualElement(event.target);
t.parent.removeElement(t);
I have this MXML that I would like to express as actionscript:
<s:titleContent>
<s:Label text="Title" fontWeight="bold" fontSize="20" height="20" verticalAlign="top" />
<s:Label text=".com" fontSize="12" height="17" verticalAlign="bottom" />
</s:titleContent>
I've tried this with no success:
var chrome:ActionBar = new ActionBar();
chromeTitle.text = "Title";
chrome.setStyle("fontSize", 20);
chrome.title = "Title";
chrome.title = chromeTitle;
How can I add css styled text to the action bar (multiple labels)? Also is it possible to make other views inherit this action bar so that I dont't have to duplicate code (all vies would have common elements)?
This syntax:
<s:titleContent>
...
</s:titleContent>
Means that you are setting the titleContent property on the component that this resides under. You can tell the difference between properties and new class instances from the case. Class names always start with an uppercase; whereas property names start with a lowercase. You didn't specify which class this is a property on; but since you're dealing with mobile I assume it is a view. the titleContent property is an array.
So; you must do this:
// create the first label and set properties
var tempLabel :Label = new Label();
tempLabel.text = 'Title';
tempLabel.setStyle('fontWeight','bold');
tempLabel.setStyle('fontSize',20);
tempLabel.height = 20;
tempLabel.setStyle('verticalAlign','top');
// add label to titleContent array
this.titleContent.push(tempLabel);
// create next label
tempLabel :Label = new Label();
tempLabel.text = '.com';
tempLabel.setStyle('fontSize',12);
tempLabel.height = 17;
tempLabel.setStyle('verticalAlign','bottom');
// add second label to titleContent array
this.titleContent.push(tempLabel);
That is the proper way to convert the MXML code you provided into ActionScript. Since your own code tried to create a new ActionBar() I'm not sure what you if this is really what you wanted.
i'm working on flex 3 project. in which i have one tileList in which there are muliple images, every images put in different canvas in tileList. i will give allowmultipleSelection to true. now i need to print all that Images on print button click, which user select from TileList.
please give me proper suggestion, how i will DO.
Thanks,
I got my answer Here, I take Tile instead of TileList and i push all Selected Image into one Array. And in printer.printPage I will Pass that Array and It will work now.
/* MyCustomItemBox */
<mx:HBox id="hb" autoLayout="false">
<mx:Image id="img" source="{imageURL}"/>
</mx:HBox>
/* Print Script */
// Custom Component which will be added in to Tile.
var myCustomBox= new MyCustomItemBox();
thumbView.addChild(myCustomBox);
// On Print Button Click
protected function onPrintPages(event:MouseEvent):void
{
var printer:Printer = new Printer();
var arr:Array = new Array();
for(var i:int = 0;i<10;i++)
{
var bdi:MyCustomItemBox = thumbView.getChildAt(i) as MyCustomItemBox;
var hb:HBox = bdi.getChildByName("hb") as HBox;
arr.push( hb.getChildByName( 'img' ) as UIComponent );
}
if(arr.length > 0)
printer.printPage(arr,null, "showAll");
}
<mx:Tile id="thumbView" autoLayout="false" width="90%" height="90%" />
I know that there is no such function as getElementByName in Flex but I also now that you can do this["object_id"] to get the element of the application u're in.
What about getting an element inside another element?
I've tried making element["id"] ? But in my try-catch it always runs the "catch" part =\
So: how do I get an element inside another element just having it's id in dynamically created string form?
Thank you in advance
It depends on what kind of element you are trying to access.
A child display object can be accessed by calling DisplayObjectContainer#getChildByName:
element.getChildByName("name");
A public variable (which could be set to also contain a child display object) can be accessed by using bracket syntax:
element["name"];
or simply using dot syntax:element.name
(where name is the name of the property you are trying to access).
Note that any instance you drag to the stage in the Flash IDE will automatically be assigned to a public variable, if you have the "automatically declare stage instances" option checked in your export settings. That is why using this[name]works.
If I understand correctly, you're asking for a way to get all the "elements" in a Flex application that have a certain name.
Here's an example (Flex 3):
<?xml version="1.0"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" xmlns="*">
<mx:Script>
<![CDATA[
private function testIt():void
{
var arr:Array = getDisplayObjectsByName(this, "foo");
for each (var e:* in arr)
trace(e);
}
private static function getDisplayObjectsByName(node:DisplayObjectContainer,
name:String, recurse:Boolean = true):Array
{
var n:int = node.numChildren;
var a:Array = [];
for (var i:int = 0; i < n; i++) {
var c:DisplayObject = node.getChildAt(i);
if (c.name == name)
a.push(c);
if (recurse) {
if (c is DisplayObjectContainer)
a = a.concat(getDisplayObjectsByName(DisplayObjectContainer(c),
name, true));
}
}
return a;
}
]]>
</mx:Script>
<mx:VBox name="foo">
<mx:HBox>
<mx:Button name="foo" label="Test" click="testIt()" />
</mx:HBox>
</mx:VBox>
<mx:Label text="Ignore Me" />
<mx:VBox name="bar">
</mx:VBox>
</mx:Application>
Here we're looking for all the elements called "foo" when the user clicks the "Test" button.
Output:
main0.foo
main0.foo.HBox5.foo
You'll notice that getDisplayObjectsByName() is static. All it does is traverse the display list (depth-first) and pick out all the objects with the specified name.
If you're looking for the element in a Group, you can use this function:
static function getElementByName(group:GroupBase, name:String):IVisualElement {
const child:DisplayObject = group.getChildByName(name);
const index:int = group.getChildIndex(child);
return group.getElementAt(index);
}
I have to create several vbox-es in a for each loop.
Now I want to do something like this.
formsArray["vb"+counter] = new VBox;
formsArray["vb"+counter].visible = true;
add labels etc.
I can't get this thing to work. Anybody any idea how to create dynamic variable names for my vbox-es?
Thanks
First off, to use an associative array, you need to use an Object and not an Array (perhaps you already are, then never mind).
You can achieve what you want to do the following way:
var vbox:VBox;
var formsArray:Object = new Object();
var counter:int = 0;
for each(<statement>)
{
vbox = new VBox();
formsArray[("vb" + counter.toString())] = vbox;
counter++;
}
The VBox's visible property is true by default, so no need to explicitly set it.
Answer to additional question in comments:
You don't really need to make use of dynamic references to do what you want to do. You'd be best of creating a custom component for this, extending the VBox class, by creating a new MXML class with VBox as the root tag. Something along these lines:
<mx:VBox ... >
<mx:Button ... click="btnClickHandler()"/>
<mx:Script>
<![CDATA[
// Toggles visibility of the VBox
private function btnClickHandler():void
{
visible = !visible;
}
]]>
</mx:Script>
</mx:VBox>
Then you can just instantiate as many of these custom VBox:es as you need. However, making the VBox invisible will make the contained button invisible as well, making it difficult to click it again. :) You probably want to address that. Anyways, I hope this will point you in the right direction.