Quick tip (Flex 4): Goodbye templates – hello mxmlContent
October 2nd, 2009
Back in Flex 3
In Flex 3 is it pretty painful to extend a custom container component for adding children to it using MXML. The following example will throw an error like this: Error: Multiple sets of visual children have been specified for this component (base component definition and derived component definition).
MySubContainer.mxml ( Download code )
-
<?xml version="1.0" encoding="utf-8"?>
-
<!–
-
-
class hierarchy of MySubContainer:
-
-
Canvas
-
|
-
MyContainer
-
|
-
MySubContainer
-
-
–>
-
<local:MyContainer
-
xmlns:mx="http://www.adobe.com/2006/mxml"
-
xmlns:local="*"
-
>
-
<mx:Label
-
text="subContainer"
-
/>
-
</local:MyContainer>
To avoid this issue in Flex 3 there are already some workarounds using template components. For more information check the following posts:
- Peter Ent: Template in Flex
- Tony Fendall: Adding ‘Multiple sets of visual children’ to custom components
- Dirk Eismann: A simple(r) workaround for the ‘Multiple sets of visual children’ runtime error
Today in Flex 4
Now in Flex 4 this issue has been fixed. There is no need for using custom template component if you extend Sparks Group or SkinnableContainer in multiple levels. That means there is no error using:
MySubContainer.mxml ( Download code )
-
<?xml version="1.0" encoding="utf-8"?>
-
<!–
-
class hierarchy of MySubContainer:
-
-
Group
-
|
-
MyContainer
-
|
-
MySubContainer
-
-
–>
-
<local:MyContainer
-
xmlns:fx="http://ns.adobe.com/mxml/2009"
-
xmlns:s="library://ns.adobe.com/flex/spark"
-
xmlns:mx="library://ns.adobe.com/flex/halo"
-
xmlns:local="*"
-
>
-
<s:Label
-
text="subContainer"
-
/>
-
-
</local:MyContainer>
Behind the scenes: Every Spark Group or SkinnableContainer has a property called mxmlContent, which handles internal all the needed stuff for organizing children defined by MXML. Furthermore all container classes has defined a metatag declaration named DefaultProperty
- Group:
[DefaultProperty("mxmlContent")] ) - SkinnableContainer:
[DefaultProperty("mxmlContentFactory")]
which causes the compiler to add all (top) children defined within MXML as an array to the setter method mxmlConent or mxmlContentFactory.
Important note: If you have already defined children within the super class, these will be removed by the subclass by default. To avoid this, you have to override the setter method mxmlContent of the subclass or build your own custom template component.
Happy Flex 4 coding
-Jens


October 19th, 2009 at 1:51 am
Is there a way to get all the “mxml content” not only the top level ?
April 13th, 2010 at 3:45 am
Here is an override for set mxmlContent:
//allow the addition of mxml content further up the chain – allows the subclassing of mxml components
override public function set mxmlContent(value:Array):void
{
var adding:Boolean = true;
var index:int = 0;
while ( adding ) {
var ive:IVisualElement = null;
try {
ive = super.getElementAt(index);
}
catch (e:Error) {
}
if ( ive != null ) {
value.unshift(ive);
index++;
}else{
adding = false;
}
}
super.mxmlContent = value;