# Spark SkinnableDataContainer - Functional and Design Specification
----
## Summary and Background
----
**graphic element** - A graphical element like a Rectangle, Path, or Bitmap. This element is not a subclass of DisplayObject; however, it does need a DisplayObject to render on to.
**visual element** - A visual element (a.k.a. - "element"). This can be a halo component, a gumbo component, or a **graphic element**. Visual elements implement `IVisualElement`.
**data item** (a.k.a. - "item") - Basically anything is considered a data item. Mostly it refers to a non-visual item like a String, Number, XMLNode, etc. A visual element can also be a data item--it just depends on how it's treated.
**}SkinnableContainer** \- A skinnable component with chrome that holds and lays out visual elements. It also serves as a base class for other skinnable visual containers. For example, [Panel](Panel) is a subclass of SkinnableContainer that has a border, header, and footer.
**}SkinnableDataContainer** \- A skinnable component with chrome that holds and lays out data items and supports virtualization. It also serves as a base class for other skinnable data containers. For example, List is a subclass of SkinnableDataContainer that adds support for selection, mouse handling, and key handling.
## Usage Scenario
----
The first example shows using SkinnableDataContainer as a container to show data items. The second example extends SkinnableDataContainer to create ListBase to add selection handling to SkinnableDataContainer.
### Example 1: Displaying data items in SkinnableDataContainer
<s:skinnabledatacontainer itemrenderer="myItemRenderer">
<s:layout><s:verticallayout horizontalalign="center"></s:verticallayout></s:layout>
<s:arraycollection>
<fx:object firstname="Deepa" lastname="Subramaniam" phonenumber="415-555-1111">
<fx:object firstname="Glenn" lastname="Ruehle" phonenumber="415-555-2222">
<fx:object firstname="Ely" lastname="Greenfield" phonenumber="415-555-3333">
<fx:object firstname="Alex" lastname="Harui" phonenumber="415-555-4444">
<fx:object firstname="Ryan" lastname="Frishberg" phonenumber="415-555-5555">
</fx:object></fx:object></fx:object></fx:object></fx:object></s:arraycollection>
</s:skinnabledatacontainer>
### Example 2: ListBase
package spark.components {
/**
* Dispatched when the selection is going to change.
* Calling the
preventDefault()
method
* on the event will prevent the selection from changing.
*/
Event(name="selectionChanging", type="mx.events.IndexChangedEvent")
/**
* Dispatched after the selection has changed.
*/
Event(name="selectionChanged", type="mx.events.IndexChangedEvent")
/**
* Dispatched after the focus has changed.
*/
Event(name="itemFocusChanged", type="mx.events.IndexChangedEvent")
public class ListBase extends SkinnableDataContainer
{
//--------------------------------------------------------------------------
//
// Properties
//
//--------------------------------------------------------------------------
/**
* The 0-based index of the selected item, or -1 if no item is selected.
* Setting the selectedIndex property de-selects the currently selected
* item and selects the item at the specified index.
*
* The value of selectedIndex is always pinned between -1 and
* (dataProvider.length - 1). If item's at a lower index than selectedIndex are
* removed from the component, the selected index is adjusted downward
* accordingly. If the selected item is removed, selected index is
* set to -1 (if requireSelection = false or there are no remaining items)
* or 0 (if requireSelection = true and there is at least one item).
*
* @default -1
*/
public var selectedIndex:int;
/**
* The item that is currently selected. Setting the selectedItem property
* de-selects the currently selected item and selects the specified item.
*
* Setting selectedItem to an item that is not in this component results in
* no selection, and selectedItem being set to undefined. If the selected
* item is removed, the selected item is set to undefined (if requireSelection
* = false or there are no remaining items) or the first item (if
* requireSelection = true and there is at least one item).
*
* @default undefined
*/
public var selectedItem:*;
/**
* Specifies whether an item must always be selected.
* If the value is true, the selectedIndex property will always be
* set to a value between 0 and (dataProvider.length - 1), or -1 if there are
* no items.
*
* @default false
*/
public var requiresSelection:Boolean = false;
//--------------------------------------------------------------------------
//
// Methods
//
//--------------------------------------------------------------------------
/**
* Called when an item is selected or deselected.
* Subclasses must override this method to display the selection.
*
* @param index The item index that was selected.
*
* @param selected
true
if the item is selected,
* and
false
if it is deselected.
*/
protected function itemSelected(index:int, selected:Boolean):void;
}
}
## Detailed Description
----
### SkinnableDataContainer
The SkinnableDataContainer class is basically a [Spark DataGroup](Spark%20DataGroup) with skinnable chrome. More precisely, it is a SkinnableComponent whose skin has a dataGroup. It has one SkinPart named `dataGroup`, and it facades the dataProvider, layout, viewport, and and item renderer functionality of the `dataGroup` skin part. See the API Description section for details. Because of this, SkinnableDataContainer has non-content children and is skinnable, while DataGroup can only contain the rendered data items.
## API Description
----
### SkinnableDataContainer
Most of the SkinnableDataContainer APIs are proxies to the `dataGroup` skin part. Details on these APIs can be found in the [Spark DataGroup](Spark%20DataGroup) spec.
package spark.components
{
DefaultProperty("dataProvider")
class SkinnableDataContainer extends SkinnableContainerBase
{
// NOTE: SkinnableContainerBase extends SkinnableComponent
// SkinnableContainerBase handles enabling/disabling of children and
// also an IViewport implementation needed for scrolling
//--------------------------------------------------------------------------
//
// Skin Parts
//
//--------------------------------------------------------------------------
/**
* The DataGroup that displays the content of this component. The dataProvider,
* layout, itemRenderer, and itemRendererFunction properties of the
* component are assigned to this skin part.
*/
SkinPart
public var dataGroup:DataGroup;
//--------------------------------------------------------------------------
//
// DataGroup property and method proxies
//
// The remainder of the DataContainer API are direct proxies to the
// dataGroup SkinPart.
//
// Details for these APIs can be found in the DataGroup class.
//--------------------------------------------------------------------------
//--------------------------------------------------------------------------
//
// Properties .. proxies to dataGroup
//
//--------------------------------------------------------------------------
public function get dataProvider():IList;
public function set dataProvider(value:IList):void;
public function get layout():LayoutBase;
public function set layout(value:LayoutBase):void;
public function get itemRenderer():IFactory;
public function set itemRenderer(value:IFactory):void;
public function get itemRendererFunction():Function;
public function set itemRendererFunction(value:Function):void;
public function get typicalItem():Object;
public function set typicalItem(value:Object):void;
}
}
## Prototype Work
----
An implementation of SkinnableDataContainer has been checked in. Work has been done on subclasses, ListBase and List. As more work gets done on the subclasses, some of that might be pushed into SkinnableDataContainer.
## Compiler Work
----
None.
## Web Tier Compiler Impact
----
None.
## Flex Feature Dependencies
----
[Spark DataGroup](Spark%20DataGroup) \- SkinnableDataContainer has a very tight connection with the DataGroup class, and we must keep the API's in sync.
[Spark Virtualization](Spark%20Virtualization) - This is mostly baked into DataGroup and layouts, but specced separately.
List - The list component, which extends SkinnableDataContainer, provides selection support.
ItemRenderer - Item Renderers are how data items are visualized.
## Backwards Compatibility
----
### Syntax changes
None. These are new classes.
### Behavior
None. These are new classes.
### Warnings/Deprecation
None.
## Accessibility
----
N/A
## Performance
----
These classes are bound by the performance of the DataGroup class.
## Globalization
----
Not Applicable.
## Localization
----
### Compiler Features
None.
### Framework Features
None.
## Issues and Recommendations
----
## QA
[[ include ref='flexsdk_rightnav' ]]
[[ include ref='site:open_commentlogin' ]]