Почему визуальные элементы не отображаются внутри пользовательского компонента, расширенного из другого пользовательского компонента - PullRequest
0 голосов
/ 07 сентября 2011

Я создал собственный компонент MXML, TurboContent, который расширяет класс NavigatorContent:

<s:NavigatorContent xmlns:fx="http://ns.adobe.com/mxml/2009"
        xmlns:s="library://ns.adobe.com/flex/spark"
        xmlns:mx="library://ns.adobe.com/flex/mx">

<fx:Metadata>
[DefaultProperty("mxmlContentFactory")]
</Fx:Metadata>

<s:Group id="midWrapper">
    <s:Button id="btnAdd" />
</s:Group>
<s:Group id="rightWrapper" >
    <s:DataGrid id="dgdSelect" >
        <s:columns>
            <s:ArrayList>
                <s:GridColumn headerText="Yo"></s:GridColumn>
            </s:ArrayList>
        </s:columns>
    </s:DataGrid>
    <s:Button id="btnRemove" />
    <s:Button id="btnClear" />
</s:Group>
</s:NavigatorContent>

Я пытаюсь расширить этот пользовательский компонент, но когда я добавляю элементы отображения ко второму расширенному компоненту, они никогда не отображаются. Например: (первый пользовательский компонент находится в пакете компа)

<comp:TurboContent xmlns:fx="http://ns.adobe.com/mxml/2009"
        xmlns:s="library://ns.adobe.com/flex/spark"
        xmlns:mx="library://ns.adobe.com/flex/mx"
        xmlns:comp="comp.*">

<s:Button id="myButton"/>

</comp:TurboContent>

В этом случае компонент myButton никогда не отображается, но отображаются все элементы базового компонента (3 кнопки и сетка данных).

Ответы [ 2 ]

2 голосов
/ 09 сентября 2011

Мне любопытно понять, чего ты пытаешься достичь?

Судя по фрагментам кода, вы пытаетесь создать новое представление, которое визуально наследует компонент TurboContent и добавляет к нему еще одну кнопку.

Что действительно происходит под капотом, так это то, что NavigatorContent расширяет SkinnableContainer . SkinnableContainer имеет в качестве свойства по умолчанию mxmlContentFactory , которое после инициализации не может быть изменено или заменено или добавлено поверх него, если вы не сделаете это с помощью ActionScript:

mxmlContentFactory = null; // or some IDeferredInstance

Но тогда ваш подход к визуальному наследованию будет не визуальным наследованием, а заменой контента.

Базовый класс уже инициализировал его, поэтому подклассы не могут его модифицировать.

1 голос
/ 09 сентября 2011

Из того, что я могу сказать, шаблон определения компонента непосредственно в MXML (как вы упомянули, был сделан в серии FIAW) не позволяет затем визуально вставлять дочерние элементы в список отображения контейнера. Одна из проблем заключается в том, что mxmlContent (который обычно контролирует скин) статически определяется в компоненте, и не похоже, что можно напрямую использовать contentGroup внутри компонента MXML.

Для лучшего контроля и того, что я считаю более строгой реализацией шаблона MVC (которую внедряет Flex 4 в качестве основы), попробуйте разделить ваш визуальный макет на оболочку MXML и определить компонент в AS3. 1005 *

Из того, что я вижу относительно вашего компонента, я не могу на самом деле судить о том, какие свойства компонента вы хотите представить контейнеру, который его создаст. По крайней мере, я приведу здесь пример того, как можно передавать информацию из компонента в скин.

Я прошу прощения за компоненты MX, но у меня есть только Flex 4.1, и я хотел убедиться, что программа скомпилирована нормально. Вам не должно быть слишком сложно поменять версию spark.

Пример компонента (TurboContentAS.as)

package components {

  import mx.controls.DataGrid;
  import spark.components.NavigatorContent;

  public class TurboContentAS extends NavigatorContent {

    public function TurboContentAS() {
      super();
    }

    // Skin Parts that constitute the necessary parts of the component
    [SkinPart(required="true")]
    public var dgdSelect:DataGrid;  //just an example

    // property you want to expose to the instantiating object
    [Bindable]
    public var firstColumnHeader:String = "default header";

  }
}

Пример скина (TurboContentSkin.mxml)

<?xml version="1.0" encoding="utf-8"?>
<s:Skin xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark"
        xmlns:mx="library://ns.adobe.com/flex/mx"
        alpha.disabled="0.5" >

    <fx:Metadata>[HostComponent("components.TurboContentAS")]</fx:Metadata>

    <s:states>
        <s:State name="normal" />
        <s:State name="disabled" />
    </s:states>

    <!-- this is where the children that you add later go-->
    <s:Group id="contentGroup" left="0" right="0" top="100" bottom="0" minWidth="0" minHeight="0">
        <s:layout>
            <s:BasicLayout/>
        </s:layout>
    </s:Group>
    <s:Group id="midWrapper">
        <s:Button id="btnAdd" label="Add" />
    </s:Group>
    <s:Group id="rightWrapper" left="200">
        <s:layout>
            <s:VerticalLayout/>
        </s:layout>
        <mx:DataGrid id="dgdSelect">
            <mx:columns>
                <fx:Array>
      <!-- This will bind to the publicly exposed property in the component definition -->
                    <mx:DataGridColumn  headerText="{hostComponent.firstColumnHeader}"/>
                </fx:Array>
            </mx:columns>
        </mx:DataGrid>
        <s:Button id="btnRemove" label="Remove"/>
        <s:Button id="btnClear" label="Clear"/>
    </s:Group>
</s:Skin>

Пример использования

<components:TurboContentAS skinClass="skins.TurboContentSkin" firstColumnHeader="myHeader">
        <s:Button label="myButton"/>
    </components:TurboContentAS>
...