开发者

custom MXML container in Flex 4

开发者 https://www.devze.com 2023-01-08 03:44 出处:网络
I want to make a custom container, usable in MXML like: <local:MyContainer> <s:Label/> <s:Button/>

I want to make a custom container, usable in MXML like:

<local:MyContainer>
  <s:Label/>
  <s:Button/>
  ...
</local:MyContainer>

...but I'd like to be able to catch when the children are added so that I can control stuff like when & where they're added.

I tried overriding addChild(), addChildAt(),开发者_运维百科 addElement(), addElementAt(), (extending the Group class) but they only fire when you add elements specifically with those functions - the application launches and the label, button, etc, end up in MyContainer without calling these functions.

How do I control the addition of sub-components via MXML? Am I on the wrong track - should I be writing a custom layout and/or skin instead?


You could try to overwrite the setter of the mxmlContent-Array. Probably this is used instead of addChild()...


I just found out that this works and it might be helpful for you. It has a downside. The Designer will display an error message "Multiple sets of visual children have been specified for the tag".

<?xml version="1.0" encoding="utf-8"?>
<s:Group xmlns:fx="http://ns.adobe.com/mxml/2009" 
         xmlns:s="library://ns.adobe.com/flex/spark">
    <fx:Declarations>
        <!-- Place non-visual elements (e.g., services, value objects) here -->
    </fx:Declarations>

    <fx:Script>
        <![CDATA[
            import avmplus.getQualifiedClassName;

            import flash.utils.getDefinitionByName;

            import mx.core.IVisualElement;
            import mx.core.UIComponent;

            import spark.layouts.BasicLayout;
            import spark.layouts.VerticalLayout;

            private var customMxmlContent : Array = null;
            private var customInitializeDone : Boolean = false;
            override public function set mxmlContent(value:Array) : void {

                if(!customInitializeDone) {
                    // customInitializeDone == false:
                    // this is called when the elements that are defined in THIS
                    // mxml file are added to mxmlContent. 
                    super.mxmlContent = value;
                    customInitializeDone = true;

                } else { 
                    // customInitializeDone:
                    // called when the elements from another mxmls file are added.
                    // Another file uses this component in this way:
                    /*
                    <views:RoundedGroup width="100%">
                        <views:layout>
                            <s:VerticalLayout/>
                        </views:layout>

                        <s:Button label="1234" />
                        <s:Button label="5678" />
                    </views:RoundedGroup>
                     */
                    // Here it is redirected to the innerGroup
                    // if you do not do this, the content of THIS mxml file is
                    // replaced by the other content
                    for(var i:uint=0; i < value.length; i++) {
                        innerGroup.addElement(value[i] as IVisualElement);
                    }
                }

                // Reset the layout 
                if(this.layout != null) {
                    // find out the layout class that is applied to this
                    var layClass : Class =  getDefinitionByName(getQualifiedClassName(this.layout)) as Class;
                    // and apply it to innerGroup instead
                    innerGroup.layout = new layClass();
                    // and reset the layout of this to a BasicLayout to get the Rect to the correct
                    // position and the innerGroup above the Rect
                    this.layout = new BasicLayout();
                }
            }
        ]]>
    </fx:Script>

        <s:Rect left="10" right="10" top="10" height="100%"  radiusX="11" radiusY="11">
            <s:fill>
                <s:SolidColor color="0xB7C8A8" />
            </s:fill>
            <s:stroke>
                <s:SolidColorStroke color="0xABABAB" weight="1" />
            </s:stroke>
        </s:Rect>

        <!-- Items are added within set mxmlContent to this VGroup container -->
        <s:Group id="innerGroup" left="10" right="10" top="10" />
</s:Group>
0

精彩评论

暂无评论...
验证码 换一张
取 消