将状态传递给Flex4 ButtonBar的子按钮

| 我有一个具有自定义外观的Spark ButtonBar,它为\“ middleButton \”需求定义了一个自定义外观。我的CustomButtonBarSkin有一个自定义状态,已最小化,我想将其传递给我的middleButton外观,以便它可以修改其设计。 是否有可能做到这一点?我可以看到我的按钮外观可以使用parentDocument.currentState来获取最小化状态,但这确实很丑陋。有什么方法可以将皮肤从工具栏传递到子按钮?     
已邀请:
我认为您应该扩展默认值
ButtonBar
。像这样:
package
{
import mx.core.IFactory;

import spark.components.ButtonBar;

[SkinState(\"minimized\")]
[SkinState(\"minimizedDisabled\")]
public class MinimizableButtonBar extends ButtonBar
{
    public function MinimizableButtonBar()
    {
        super();

        itemRendererFunction = defaultButtonBarItemRendererFunction;
    }

    [SkinPart(required=\"true\", type=\"mx.core.IVisualElement\")]
    public var middleButtonMinimized:IFactory;

    private var _minimized:Boolean;

    [Bindable]
    public function get minimized():Boolean
    {
        return _minimized;
    }

    public function set minimized(value:Boolean):void
    {
        if (_minimized == value)
            return;

        _minimized = value;
        invalidateSkinState();
        itemRendererFunction = defaultButtonBarItemRendererFunction;
    }

    override protected function getCurrentSkinState():String
    {
        if (_minimized)
            return enabled ? \"minimized\" : \"minimizedDisabled\";
        return super.getCurrentSkinState();
    }

    private function defaultButtonBarItemRendererFunction(data:Object):IFactory
    {
        var i:int = dataProvider.getItemIndex(data);
        if (i == 0)
            return firstButton ? firstButton : (_minimized ? middleButtonMinimized : middleButton);

        var n:int = dataProvider.length - 1;
        if (i == n)
            return lastButton ? lastButton : (_minimized ? middleButtonMinimized : middleButton);

        return (_minimized ? middleButtonMinimized : middleButton);
    }
}
}
因此,使用此代码,您可以通过以下方式声明自定义外观:
<?xml version=\"1.0\" encoding=\"utf-8\"?>
<s:Skin alpha.disabledGroup=\"0.5\" xmlns:fx=\"http://ns.adobe.com/mxml/2009\" xmlns:s=\"library://ns.adobe.com/flex/spark\">
    <fx:Metadata>[HostComponent(\"MinimizableButtonBar\")]</fx:Metadata>

    <s:states>
        <s:State name=\"normal\" />
        <s:State name=\"disabled\" stateGroups=\"disabledGroup\" />
        <s:State name=\"minimized\" stateGroups=\"minimizedGroup\" />
        <s:State name=\"minimizedDisabled\" stateGroups=\"disabledGroup,minimizedGroup\" />
    </s:states>

    <fx:Declarations>
        <fx:Component id=\"firstButton\">
            <s:ButtonBarButton skinClass=\"spark.skins.spark.ButtonBarFirstButtonSkin\" />
        </fx:Component>
        <fx:Component id=\"middleButton\">
            <s:ButtonBarButton skinClass=\"spark.skins.spark.ButtonBarMiddleButtonSkin\" />
        </fx:Component>
        <fx:Component id=\"middleButtonMinimized\">
            <s:ButtonBarButton skinClass=\"MinimazedButtonBarMiddleButtonSkin\" />
        </fx:Component>
        <fx:Component id=\"lastButton\">
            <s:ButtonBarButton skinClass=\"spark.skins.spark.ButtonBarLastButtonSkin\" />
        </fx:Component>
    </fx:Declarations>

    <s:DataGroup height=\"100%\" id=\"dataGroup\" width=\"100%\">
        <s:layout>
            <s:ButtonBarHorizontalLayout gap=\"-1\" />
        </s:layout>
        <s:layout.minimizedGroup>
            <s:VerticalLayout />
        </s:layout.minimizedGroup>
    </s:DataGroup>
</s:Skin>
希望这能解决您的问题。 而且,如果最小化状态仅涉及更改中间按钮的外观,则可以从自定义组件和外观中删除所有与状态相关的代码。     
我最近正在为按钮栏设置外观,并希望扩展/删除某些默认行为。而不是扩展和覆盖或复制/粘贴ButtonBar代码,我只是滚动了自己的简约组件:。
public class HButtonBarGroup extends HGroup {

    public function HButtonBarGroup() {
        addEventListener(ElementExistenceEvent.ELEMENT_ADD, refreshSkins);
        super();
        gap = -1;
    }

    private function refreshSkins(event : * = null) : void {
        var buttonCount : int = numElements;

        for (var i : int = 0; i < buttonCount; i++) {
            var button : Button = getElementAt(i) as Button;
            var skinClass : Class

            if ((buttonCount == 0) || (buttonCount > 2 && (i != 0 && i != buttonCount)))
                skinClass = GreyButtonBarMiddleButtonSkin;
            else if (i == 0)
                skinClass = GreyButtonBarFirstButtonSkin;
            else
                skinClass = GreyButtonBarLastButtonSkin;

            Button(getElementAt(i)).setStyle(\"skinClass\", skinClass);
        }
    }
}
这将使您能够执行大多数所需的操作,而不必tip着脚步围绕ButtonBar,ButtonBarBase和ButtonBarSkin-除非您想要togglebutton / selectedIndex,否则所有这些操作都是不必要的。 IMO很难创建基于dataProvider的按钮,而不仅仅是在MXML中声明按钮并在那里分配处理程序和其他属性。     
我最近需要根据其父状态更改组件上的外观。我使用了与CSS相同的HTML解决方案。就您而言,类似:
s|ButtonBar:minimized s|ButtonBarButton {
    skinClass: ClassReference(\"CustomButtonBarSkin\");
}
s|ButtonBarButton {
    skinClass: ClassReference(\"spark.skins.spark.ButtonBarMiddleButtonSkin\");
}
:minimized是伪选择器(用于状态)。 不幸的是,除非我在状态更改时更改了父元素的styleName,否则它似乎不会被子对象(bug?)所困扰:
<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\"
    styleName.normal=\"foo\" styleName.minimized=\"foo\"
    >
也许我应该呼吁父母改变状态,以使孩子接受改变,但只是将styleName更改为伪造的方法。 由于Flex 3仅支持基本的CSS选择器,因此这可能不是Flex中广泛使用的技术。     
也许我没有弄清楚您要尝试做的事情,但是对我来说,这似乎很明显并且很容易。当最小化状态处于活动状态时,只需让您的自定义按钮栏外观设置中间按钮的状态即可:
<s:Skin>

<s:states>
<s:State name=\"minimized\" />
</s:states>

<s:ButtonBarButton currentState.minimized=\"someState\" />

</s:Skin>
得到它?     

要回复问题请先登录注册