2011-07-13 48 views
3

對不起,這可能是一個很容易回答的問題,但如何在Flex中可以指出該列表爲空Spark List組件中顯示一條消息。例如,如果我有一個顯示的工作出色數的列表,如果我的列表是空的話,我想整個列表中顯示的消息,指出「有沒有工作來執行」。顯示一條消息,一個星火列表爲空

因爲那是一個項目(該列表不爲空)和項目可以選擇,我寧願不使用項目渲染器。

這似乎應該是很瑣碎,我希望它是。

由於提前, 菲爾

回答

6

你可以用,將只顯示如果dataProvider沒有項目,像這樣的覆蓋工作:

<s:List dataProvider="{dp}" left="0" right="0" top="0" bottom="0" /> 

<s:Group id="emptyMsgBox" left="0" right="0" top="0" bottom="0" alpha=".7" 
     visible="{!dp.length}" includeInLayout="{!dp.length}"> 

    <s:Rect left="0" right="0" top="0" bottom="0"> 
     <s:fill> 
      <s:SolidColor color="0x000000" /> 
     </s:fill> 
    </s:Rect> 

    <s:Label text="no items in list" color="0xffffff" 
      verticalCenter="0" horizontalCenter="0" /> 
</s:Group> 

你也可以使用的狀態,而不是'visible','includeInLayout'和'dp.length'之間的綁定

編輯:如果您想要在所有List組件中使用此行爲,可以爲List創建自定義外觀,如t他:

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

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

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

    <s:Rect left="0" right="0" top="0" bottom="0" id="border"> 
     <s:stroke> 
      <s:SolidColorStroke id="borderStroke" weight="1"/> 
     </s:stroke> 
    </s:Rect> 

    <s:Rect id="background" left="1" right="1" top="1" bottom="1" > 
     <s:fill> 
      <s:SolidColor id="bgFill" color="0xFFFFFF" /> 
     </s:fill> 
    </s:Rect> 

    <s:Scroller id="scroller" left="0" top="0" right="0" bottom="0" 
       minViewportInset="1" hasFocusableChildren="false"> 

     <s:DataGroup id="dataGroup" 
        itemRenderer="spark.skins.spark.DefaultItemRenderer"> 
      <s:layout> 
       <s:VerticalLayout gap="0" horizontalAlign="contentJustify" 
            requestedMinRowCount="5" /> 
      </s:layout> 
     </s:DataGroup> 
    </s:Scroller> 

    <s:Group id="emptyMsgBox" left="0" right="0" top="0" bottom="0" alpha=".7" 
      visible="{!dataGroup.dataProvider.length}" 
      includeInLayout="{!dataGroup.dataProvider.length}"> 

     <s:Rect left="0" right="0" top="0" bottom="0"> 
      <s:fill> 
       <s:SolidColor color="0x000000" /> 
      </s:fill> 
     </s:Rect> 

     <s:Label text="no items in list" color="0xffffff" 
       verticalCenter="0" horizontalCenter="0" /> 
    </s:Group> 

</s:Skin> 

這是皮膚類的下調版本,但概括地說:你要做的是,覆蓋集團在完全相同的方式添加到原星火ListSkin如前面的示例所示。 用CSS將它應用到所有組件列表:

s|List { 
    skinClass: ClassReference("my.custom.skin.ListSkin"); 
} 
+0

這是絕對精彩和工程就像一個魅力。在第一個例子我也必須從「疊加」的ID重命名爲別的,因爲它出錯:「試圖從初始化MXML只讀繼承屬性‘覆蓋’。」不過謝謝。這正是我想要的答案。 – Phil

+0

是的。如果你把它放在另一個擴展'GroupBase'的組件中,它會抱怨,因爲'GroupBase'已經有一個'overlay'屬性。我會編輯它。 – RIAstar

+0

應該編輯爲僅使用蒙皮路線。另一種方式是駭人聽聞。 –

0

你可以使用我已經與所需的功能創建的列表:

package 
{ 
import flash.events.Event; 

import mx.collections.IList; 

import spark.components.List; 
import spark.components.supportClasses.TextBase; 

[SkinState("disabledEmpty")] 
[SkinState("normalEmpty")] 
public class ListWithMessage extends List 
{ 
    [SkinPart(required = "false")] 
    public var emptyMessageLabel:TextBase; 

    /** 
    * @inheritDoc 
    */ 
    override public function set dataProvider(value:IList):void 
    { 
     super.dataProvider = value; 

     invalidateSkinState(); 
    } 

    //-------------------------------------- 
    // emptyMessage 
    //-------------------------------------- 

    private var _emptyMessage:String = "Empty"; 

    public function get emptyMessage():String 
    { 
     return _emptyMessage; 
    } 

    public function set emptyMessage(value:String):void 
    { 
     if (_emptyMessage == value) 
      return; 
     _emptyMessage = value; 
     invalidateProperties(); 
    } 

    /** 
    * @inheritDoc 
    */ 
    override protected function commitProperties():void 
    { 
     super.commitProperties(); 

     if (emptyMessageLabel) 
      emptyMessageLabel.text = _emptyMessage; 
    } 

    /** 
    * @inheritDoc 
    */ 
    override protected function getCurrentSkinState():String 
    { 
     var state:String = super.getCurrentSkinState(); 
     if (isListEmpty()) 
      state += "Empty"; 
     return state; 
    } 

    /** 
    * @inheritDoc 
    */ 
    override protected function partAdded(partName:String, instance:Object):void 
    { 
     super.partAdded(partName, instance); 

     if (instance == emptyMessageLabel) 
      emptyMessageLabel.text = _emptyMessage; 
    } 

    private function isListEmpty():Boolean 
    { 
     return !dataProvider || dataProvider.length == 0; 
    } 

    /** 
    * @inheritDoc 
    */ 
    override protected function dataProvider_collectionChangeHandler(event:Event):void 
    { 
     super.dataProvider_collectionChangeHandler(event); 

     invalidateSkinState(); 
    } 
} 
} 

此列表範例皮膚:

<?xml version="1.0" encoding="utf-8"?> 
<s:SparkSkin xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" 
     xmlns:fb="http://ns.adobe.com/flashbuilder/2009" minWidth="112" 
     alpha.disabledGroup="0.5" blendMode="normal"> 
    <fx:Metadata>[HostComponent("ListWithMessage")]</fx:Metadata> 

    <fx:Script fb:purpose="styling"> 
     /* Define the skin elements that should not be colorized. 
      For list, the skin itself is colorized but the individual parts are not. */ 
     static private const exclusions:Array = ["scroller", "background"]; 

     /** 
     * @private 
     */ 
     override public function get colorizeExclusions():Array {return exclusions;} 

     /* Define the content fill items that should be colored by the "contentBackgroundColor" style. */ 
     static private const contentFill:Array = ["bgFill"]; 

     /** 
     * @private 
     */ 
     override public function get contentItems():Array {return contentFill}; 

     /** 
     * @private 
     */ 
     override protected function initializationComplete():void 
     { 
      useChromeColor = true; 
      super.initializationComplete(); 
     } 

     /** 
     * @private 
     */ 
     override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void 
     { 
      if (getStyle("borderVisible") == true) 
      { 
       border.visible = true; 
       background.left = background.top = background.right = background.bottom = 1; 
       scroller.minViewportInset = 1; 
      } 
      else 
      { 
       border.visible = false; 
       background.left = background.top = background.right = background.bottom = 0; 
       scroller.minViewportInset = 0; 
      } 

      borderStroke.color = getStyle("borderColor"); 
      borderStroke.alpha = getStyle("borderAlpha"); 

      super.updateDisplayList(unscaledWidth, unscaledHeight); 
     } 
    </fx:Script> 

    <s:states> 
     <s:State name="normal" stateGroups="normalGroup" /> 
     <s:State name="disabled" stateGroups="disabledGroup" /> 
     <s:State name="normalEmpty" stateGroups="emptyGroup,normalGroup" /> 
     <s:State name="disabledEmpty" stateGroups="emptyGroup,disabledGroup" /> 
    </s:states> 

    <fx:Declarations> 
     <!--- 
       Defines the appearance of the the List's drop indicator. 
       To customize the drop indicator appearance, create a custom ListSkin class. 
       The List's layout takes care to size and position the dropIndicator. 
       The size of the <code>dropIndicator</code> is typically set to the size of the gaps between the items. 
       The minimum and maximum settings are typically respected only in the direction 
       along the major axis (the gap axis). For example a VerticalLayout ignores the 
       <code>minWidth</code> and <code>maxWidth</code> settings, 
       but respect <code>minHeight</code> and <code>maxHeight</code>. 

       @copy spark.components.List#dropIndicator 
     --> 
     <fx:Component id="dropIndicator"> 
      <s:Group minWidth="3" minHeight="3" maxWidth="3" maxHeight="3"> 
       <s:Rect left="0" right="0" top="0" bottom="0"> 
        <s:fill> 
         <!--- Defines the color of the background. --> 
         <s:SolidColor color="0xBBBBBB" /> 
        </s:fill> 
        <s:stroke> 
         <s:SolidColorStroke color="0x868686" weight="1"/> 
        </s:stroke> 
       </s:Rect> 
      </s:Group> 
     </fx:Component> 
    </fx:Declarations> 

    <!-- border --> 
    <!--- @private --> 
    <s:Rect left="0" right="0" top="0" bottom="0" id="border"> 
     <s:stroke> 
      <!--- @private --> 
      <s:SolidColorStroke id="borderStroke" weight="1"/> 
     </s:stroke> 
    </s:Rect> 

    <!-- fill --> 
    <!--- Defines the background appearance of the list-based component. --> 
    <s:Rect id="background" left="1" right="1" top="1" bottom="1" > 
     <s:fill> 
     <!--- Defines the color of the background. The default color is 0xFFFFFF. --> 
      <s:SolidColor id="bgFill" color="0xFFFFFF" /> 
     </s:fill> 
    </s:Rect> 

    <!--- The Scroller component to add scroll bars to the list. --> 
    <s:Scroller left="0" top="0" right="0" bottom="0" id="scroller" minViewportInset="1" hasFocusableChildren="false"> 
     <!--- @copy spark.components.SkinnableDataContainer#dataGroup --> 
     <s:DataGroup id="dataGroup" itemRenderer="spark.skins.spark.DefaultItemRenderer"> 
      <s:layout> 
       <!--- The default layout is vertical and measures at least for 5 rows. 
       When switching to a different layout, HorizontalLayout for example, 
       make sure to adjust the minWidth, minHeihgt sizes of the skin --> 
       <s:VerticalLayout gap="0" horizontalAlign="contentJustify" requestedMinRowCount="5" /> 
      </s:layout> 
     </s:DataGroup> 
    </s:Scroller> 

    <s:Label id="emptyMessageLabel" fontSize="16" fontWeight="bold" color="#333333" verticalCenter="0" 
     horizontalCenter="0" width="100%" textAlign="center" includeIn="emptyGroup" /> 
</s:SparkSkin> 

使用範例:

<?xml version="1.0" encoding="utf-8"?> 
<s:Application minHeight="600" minWidth="955" xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:local="*" 
    xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:s="library://ns.adobe.com/flex/spark"> 

    <fx:Script> 
    <![CDATA[ 
     import mx.collections.ArrayCollection; 

     protected function button1_clickHandler(event:MouseEvent):void 
     { 
      var item:Object = { label: Math.random() }; 
      if (list.dataProvider) 
       list.dataProvider.addItem(item); 
      else 
      { 
       var dp:ArrayCollection = new ArrayCollection(); 
       dp.addItem(item); 
       list.dataProvider = dp; 
      } 

     } 
    ]]> 
    </fx:Script> 

    <s:VGroup horizontalCenter="0" verticalCenter="0"> 
     <local:ListWithMessage allowMultipleSelection="false" emptyMessage="Empty List" enabled="{listEnabled.selected}" 
      height="400" id="list" skinClass="ListWithMessageSkin" width="400" /> 
     <s:CheckBox id="listEnabled" selected="true" label="List enabled" /> 
     <s:Button click="button1_clickHandler(event)" label="Add Item" /> 
     <s:Button click="list.dataProvider.removeItemAt(list.selectedIndex)" enabled="{list.selectedItem}" 
      label="Remove Item" /> 
    </s:VGroup> 
</s:Application> 

希望這有助於!