2011-04-16 11 views
1

「middleButton」要件のカスタムスキンを定義するカスタムスキンを持つSpark ButtonBarがあります。私のCustomButtonBarSkinは、私のmiddleButtonスキンに渡してそのデザインを変更できるように、を最小化したのカスタム状態を持っています。Flex4 ButtonBarの子ボタンに状態を渡す

これは可能ですか?私のボタンのスキンは、最小化状態を取得するためにparentDocument.currentStateを使用することができますが、それは本当に醜いことがわかります。バーから子ボタンにスキンを渡す方法はありますか?

答えて

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> 

・ホープこれはあなたの問題を解決し、このような何か。

最小化された状態が中ボタンスキンを変更する場合にのみ、カスタムコンポーネントとスキンの両方からすべての状態関連コードを削除できます。

+0

私は既に最小化状態を維持するためにButtonBarの拡張を持っていますので、あなたの答えは実際に私が考えていたものと一線を画しています。私は、アイテムレンダラーの機能のオーバーライドについては知らなかったが、私はそのトリックを行うだろうと思う。 1つのmiddleButton宣言だけを持ち、その上でスキンを切り替えたり、宣言のスキンで状態を設定する方法はありますか? – Michael

+0

ご覧のとおり、ボタンは「IFactory」として表されます。したがって、宣言的に状態を設定する方法はないようです。 1つの宣言だけを持ってスキンを切り替えるのはどうでしょうか?通常の 'List'のアイテムレンダラーと同じ方法が考えられます。ボタンのスキンはレンダラーであり、 'ButtonBar'は一種のリストであることを覚えておいてください。したがって、データプロバイダーのフィールド値を変更して、レンダラーに別の状態を切り替えるよう通知することができます。 – Constantiner

+0

このソリューションは機能しますが、最小化された中間ボタンのSkinPart.required = trueプロパティを削除する必要がありましたが、理由はわかりません。私は、必要なSkinPartとして最小化されたボタンを持っている場合、私は実行時の例外が、必要な部分が欠落していることを宣言しても、それが依然として必要な部分であることを望むであろう。その上の任意のアイデア? – Michael

0

私は最近、ボタンバーのスキニングを行っていて、デフォルトの動作の一部を拡張/削除したいと思っていました。 &を上書きするか、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); 
     } 
    } 
} 

これはあなたのButtonBar、ButtonBarBase周りつま先することなく、あなたが望むほとんど何もする能力を与えるだろう、とButtonBarSkin - すべての不要なあなたはトグルボタン/ selectedIndexのを望んでいない限り。 IMOでは、MXMLでボタンを宣言し、そこにハンドラやその他のプロパティを割り当てるのではなく、dataProviderに基づいてボタンを作成するのは苦痛です。

+0

ありがとう、ケビン、それは素晴らしい提案です。 ButtonBar拡張機能が私の望むように機能しない場合は、ここで提案したようなものを試してみます。 – Michael

0

最近、親の状態に基づいてコンポーネントのスキンを変更する必要がありました。 CSSを使ってHTMLで使ったのと同じソリューションを使いました。あなたのケースでは、何かのように:

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

:最小化は(米国の場合)Pseudo Selectorです。私は状態変化の親要素には、styleNameを変更しない限り、

残念ながら、これは、子(?バグ)によってピックアップを取得していないようでした:

<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では広く使用されている技術ではないかもしれません。

0

多分私はあなたが正確にやろうとしていることを得ていませんが、それはかなり明らかで簡単です。最小化された状態がアクティブなときにあなたのカスタムボタンバーのスキンに中間ボタンの状態を設定させてください:

<s:Skin> 

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

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

</s:Skin> 

それを得る?

関連する問題