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 )

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <!–
  3.  
  4.     class hierarchy of MySubContainer:
  5.    
  6.     Canvas
  7.         |
  8.         MyContainer
  9.             |
  10.             MySubContainer
  11.         
  12. –>
  13. <local:MyContainer
  14.     xmlns:mx="http://www.adobe.com/2006/mxml"
  15.     xmlns:local="*"
  16.     >   
  17.     <mx:Label
  18.         text="subContainer"
  19.         />
  20. </local:MyContainer>

To avoid this issue in Flex 3 there are already some workarounds using template components. For more information check the following posts:

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 )

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <!–
  3.     class hierarchy of MySubContainer:
  4.  
  5.     Group
  6.         |
  7.         MyContainer
  8.             |
  9.             MySubContainer
  10.  
  11. –>
  12. <local:MyContainer
  13.     xmlns:fx="http://ns.adobe.com/mxml/2009"
  14.     xmlns:s="library://ns.adobe.com/flex/spark"
  15.     xmlns:mx="library://ns.adobe.com/flex/halo"
  16.     xmlns:local="*"
  17.     >   
  18.     <s:Label
  19.         text="subContainer"
  20.         />
  21.    
  22. </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

2 Responses to “Quick tip (Flex 4): Goodbye templates – hello mxmlContent”

  1. sep Says:

    Is there a way to get all the “mxml content” not only the top level ?

  2. Caspar Says:

    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;

Leave a Reply

Follow sectore on Twitter