I’ve just come across an error when extending your own MXML components that in my opinion is a major limitation for MXML.
If you create you own MXML component that extends a VBox…
[code]
[/code]
If you then extend this component with MXML you can’t add any more DisplayObjects…
[code]
[/code]
It seems logical to me that the super class would have its DisplayObjects created first and then the sub class, but instead you get this error.
Error: Multiple sets of visual children have been specified for this component (base component definition and derived component definition).
Surely developers will want to extend their own components on a regular basis and add new DisplayObjects. I really hope this is fixed for the final release!!!

Hi Stephen. The limitation is unfortunate, but there for a reason. When it comes to making decisions like ‘what should happen if there are children both in the definition and in the use of an MXML component?’ we have three choices.
1) See a clear and obvious answer that solves 80-90+% of the use cases, and go ahead and implement it.
2) Find that no one solution solves a clear majority of uses, so instead define a mechanism by which the developer can define and describe exactly what should happen. or
3) pick an arbitrary one of N possible equally valid solutions and just go with it.
(1) is great if it exists, (2) is great if you’ve got the time to do it. But in this case we felt like just pretending the instance children were added to the end of the definition children was a version of (3). While in some use cases that might be the right thing to do, I think it’s far more common that the developer would want to direct a different purpose or placement for those instance children (or, just as often, prevent developers from specifying instance children at all). And the problem with choosing a solution that only solves the plurality of use cases (as opposed to a clear majority) is that it can get in the way of doing (2) at some point in the future…i.e., putting in a real solution that solves everyone’s use cases.
So we definitely agree that it would be valuable to be able to define both definition and instance children, but we want to make sure we can give the developer/designer the chance to dictate what that means declaratively. We actually spec’d out a solution a while back, but weren’t able to get to it in this release. Hopefully you’ll see it in a future release of the SDK.
In the meantime, there actually is a way you can achieve the effect you want today. Flex 2.0 allows you to designate a property on your component as the ‘default’ property. When you specify a default property, you are essentially telling the compiler that when someone uses your component in MXML, whatever they put inside the tag is really a value to be assigned to your defaultProperty.
So, to get the behavior you’re looking for (which we sometimes refer to as templating), you can:
1) define a new property setter that’s going to receive the content of your tag at runtime. If you want to limit the content to be just a single component, type it as a UIComponent:
public function set contentChild(value:UIComponent):void …
if you want to support multiple children, try typing it as an array:
public funciton set contentChildren(value:Array):void …
2) in the setter, write a snippet of actionscript to place those components exactly where you want them:
public funciton set contentChild(value:UIComponent):void
{
myInternalContentHolderHBox.addChild(value);
}
3) define this new property as the default in the metadata section of your MXML component:
[DefaultProperty("contentChild")]
Now, when someone uses your component in MXML, anything placed inside the tag will be rerouted to your contentChild property.
The nice thing about this solution is that it scales up well to components that have different types if content. Imagine, for example, writing a more complex Panel component that allowed you to specify the content of the panel, the header of the panel, the footer of the panel, and the status area. Instead of writing one ‘content’ property, you simply write four of them:
[XML]
[/XML]
We’d love it if this were solved with just a simple tag in your component indicating where that property goes
Hope that all makes sense and sounds reasonable.
Ely.
Architect, Flex SDK.
[...] ing lots in the comments (and i can’t get the mxml to display in the comments). Heres the original post, and the response and Ely’s solution… When it comes to making decisi [...]
Hey Tink, Peter Ent provides confirmation of Ely’s response in this article on his blog http://weblogs.macromedia.com/pent/archives/2006/03/component_templ.cfm The source code is available to download.
It’s definately something that will come in handy when you start creating your own custom components. The example in Peter’s source code includes a custom panel wrapped in a canvas, and by using the DefaultProperty metadata and an array of components that need to be added we can fully “customize the customized”.
Enjoy!
Thanks for that Andrew
I did actually get a couple of well explained examples from Ely after his post I just haven’t got my arse in gear yet to post em.
I’m very surprised and disapointed by the answer of Ely. I worked for a long time with OpenLaszlo which proposes a similar approach. In OpenLaszlo there is no problem with defining a component and declaring the place where other elements will be inserted. This is achieve with a dedicated tag. The XML is very similar. However I can understand Ely’s anser, I can not understand why Adobe doesn’t propose this most interesting possibility.
it would have been really helpful if it was a compile time error rather than throwing it on my face at run-time
Awesome article! Perfect solution for my problem.
Just a note so others can avoid my pain, the word function is misspelled above, so don’t cut and paste.
Also, and more important, FlexBuilder chokes on this: [DefaultProperty(’contentChild’)], but if you use double quotes it’s find.
Thanks Peter, I’ve addressed those errors.
I am working on a Retail Product being built on Flex UI. We need to provide a way to customers to customize the Out Of Box forms. Customers should be able to extend the base form and change the form layout and add/remove some fields on the base form. What would be best way of providing this functionality. Any help and pointers of great help.
You have to declare DefaultProperty in Actionscript file, and you can only extends it for 1 level, there’s no way you extend a extended.
This is not cool, Adobe should defintely fix this.
2Gary: You should submit your vote to the issue
“Bindable metadata should be inheritable or a warning should be generate
when a getter is overridden when the metadata is not present” if you want metadata to be inheritable
http://bugs.adobe.com/jira/browse/SDK-14251
http://blog.pigdev.com/?p=26
this is what u want!
@chen
I think Ely’s workaround is much cleaner, and doesn’t leave other uses having to know the name of the child in the base class that they can add children to.
check this article and comments, also i can send you my example by e-mail
http://cookbooks.adobe.com/post_Adding_multiple_sets_of_visual_children_to_custom-12927.html
A workable solution for multiple inheritance is to do what Adobe suggestes (until Flex 4 is released):
[DefaultProperty("mxmlContent")]
<![CDATA[
import mx.containers.HBox;
import mx.core.UIComponent;
[InstanceType("mx.controls.Label")]
public var mxmlContent:IDeferredInstance;
// Define an Array of deferred properties
// for a row of components.
// Restrict the type of the component
// to mx.controls.Button.
[InstanceType("mx.controls.Button")]
[ArrayElementType("mx.core.IDeferredInstance")]
public var mxmlContentArray:Array;
private function init():void {
if (mxmlContent) {
addChild(UIComponent(mxmlContent.getInstance()));
}
if (mxmlContentArray) {
var controlHBox:HBox = new HBox();
for (var i:int = 0; i
Same solution as everyone else suggested Will, just 3.5 years later