2010-07-22 55 views
1

我想打一個自定義的容器,就像在MXML可用:自定義MXML容器4

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

...但我希望能夠趕上的時候,孩子被添加,使我可以控制一些東西,比如當他們被添加時他們的位置&。我試過覆蓋addChild(),addChildAt(),addElement(),addElementAt(),(擴展Group類),但它們只會在你用這些函數特別添加元素時觸發 - 應用程序啓動和標籤,按鈕等,最終在MyContainer中不需要調用這些函數。

如何控制通過MXML添加子組件?我在錯誤的軌道上 - 我應該寫一個自定義佈局和/或皮膚嗎?

回答

2

你可以嘗試覆蓋mxmlContent-Array的setter。可能這是用來代替addChild()...

+0

感謝您的回答 - 您是對的,它就是這樣。查看Group的源代碼,似乎Group在內部使用私有函數elementAdded()來完成添加元素的真正工作。換句話說,SDK會避免爲MXML元素調用addElement。 但是,註釋「此方法由Flex內部使用,不適合開發人員直接使用」。在該方法的前面讓我對使用它感到不安。必須詳細瞭解自定義佈局... – Kricket 2010-07-22 09:42:49

1

我剛發現這個工作,它可能會對你有所幫助。它有一個缺點。設計器將顯示錯誤消息「爲標籤指定了多組可視化子項」。

<?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>