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

时间:2011-04-16 05:28:23

标签: flex flex4 buttonbar flex-spark

我有一个Spark ButtonBar,它有一个自定义皮肤,为“middleButton”要求定义了一个自定义皮肤。我的 CustomButtonBarSkin 有一个自定义状态,最小化,我想将其传递到我的middleButton皮肤,以便它可以修改它的设计。

有可能这样做吗?我可以看到我的按钮外观可以使用parentDocument.currentState来获取最小化状态,但这真的很难看。有没有办法将皮肤从条形图传递到子按钮?

4 个答案:

答案 0 :(得分:2)

我认为你应该扩展默认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>

希望这能解决你的问题。

如果你的最小化状态只是改变中间按钮皮肤,你可以从自定义组件和皮肤中删除所有状态相关的代码。

答案 1 :(得分:0)

我最近正在处理按钮栏的外观,并希望扩展/删除一些默认行为。而不是扩展&amp;覆盖或复制/粘贴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手to脚地绕着ButtonBar,ButtonBarBase和ButtonBarSkin - 所有这些都是不必要的,除非你想要togglebutton / selectedIndex。 IMO很难创建基于dataProvider的按钮,而不仅仅是在MXML中声明按钮并在那里分配处理程序和其他属性。

答案 2 :(得分:0)

我最近需要根据父级状态更改组件的外观。我使用了与HTML相同的解决方案,使用CSS。在你的情况下,像:

s|ButtonBar:minimized s|ButtonBarButton {
    skinClass: ClassReference("CustomButtonBarSkin");
}
s|ButtonBarButton {
    skinClass: ClassReference("spark.skins.spark.ButtonBarMiddleButtonSkin");
}

:最小化Pseudo Selector(对于州)。

不幸的是,除非我在状态更改时更改了父元素上的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中广泛使用的技术,因为Flex 3仅支持基本的CSS选择器。

答案 3 :(得分:0)

也许我没有得到你想要做的事情,但对我来说这似乎相当明显和容易。当最小化状态处于活动状态时,只需让您的客户按钮栏皮肤设置中间按钮的状态:

<s:Skin>

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

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

</s:Skin>

得到它?

相关问题