package
{
import mx.controls.Tree;
import mx.controls.treeClasses.TreeItemRenderer;
import mx.events.ListEvent;
import mx.events.TreeEvent;
import spark.components.ComboBox;
public class ComboBox extends spark.components.ComboBox
{
private var _dataSource:XML;
[SkinPart]
public var tree:Tree;
public var treeSelectedObject:Object;
public function ComboBox()
{
super();
}
[Bindable]
public function get dataSource():XML
{
return _dataSource;
}
public function set dataSource(value:XML):void
{
_dataSource = value;
}
override protected function partAdded(partName:String, instance:Object):void{
super.partAdded(partName,instance);
if(tree==instance){
tree.dataProvider=dataSource;
tree.addEventListener(ListEvent.CHANGE,onTreeClick);
tree.addEventListener(TreeEvent.ITEM_OPEN,onTreeItemOpen);
}
}
protected function onTreeItemOpen(event:TreeEvent):void
{
if (treeSelectedObject && !tree.isItemOpen(treeSelectedObject))
{
tree.selectedItem=this.treeSelectedObject;
tree.expandItem(tree.selectedItem, true);
expandParents(tree.selectedItem);
}
}
public function expandParents(node:Object):void
{
if (node && !tree.isItemOpen(node))
{
tree.expandItem(node, true);
expandParents(node.parent());
}
}
protected function onTreeClick(event:ListEvent):void
{
treeSelectedObject=TreeItemRenderer(event.itemRenderer).data;
this.textInput.text=TreeItemRenderer(event.itemRenderer).data.@label;
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<!--
ADOBE SYSTEMS INCORPORATED
Copyright 2008 Adobe Systems Incorporated
All Rights Reserved.
NOTICE: Adobe permits you to use, modify, and distribute this file
in accordance with the terms of the license agreement accompanying it.
-->
<!--- The default skin class for the Spark ComboBox component.
The skin for the anchor button for a ComboBox component
is defined by the ComboBoxButtonSkin class. The skin for the text input
is defined by the ComboBoxTextInputSkin class.
@see spark.components.ComboBox
@see spark.skins.spark.ComboBoxButtonSkin
@langversion 3.0
@playerversion Flash 10
@playerversion AIR 1.5
@productversion Flex 4
-->
<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" alpha.disabled=".5" xmlns:mx="library://ns.adobe.com/flex/mx">
<!-- host component -->
<fx:Metadata>
<![CDATA[
/**
* @copy spark.skins.spark.ApplicationSkin#hostComponent
*/
[HostComponent("ComboBox")]
]]>
</fx:Metadata>
<fx:Script fb:purpose="styling">
<![CDATA[
private var paddingChanged:Boolean;
private var cornerRadiusChanged:Boolean;
private var cornerRadius:Number = 0;
override protected function commitProperties():void
{
super.commitProperties();
if (paddingChanged && textInput)
{
// Push padding styles into the textDisplay
var padding:Number;
padding = getStyle("paddingLeft");
if (textInput.getStyle("paddingLeft") != padding)
textInput.setStyle("paddingLeft", padding);
padding = getStyle("paddingTop");
if (textInput.getStyle("paddingTop") != padding)
textInput.setStyle("paddingTop", padding);
padding = getStyle("paddingRight");
if (textInput.getStyle("paddingRight") != padding)
textInput.setStyle("paddingRight", padding);
padding = getStyle("paddingBottom");
if (textInput.getStyle("paddingBottom") != padding)
textInput.setStyle("paddingBottom", padding);
paddingChanged = false;
}
if (cornerRadiusChanged)
{
cornerRadiusChanged = false;
/* var cr:Number = getStyle("cornerRadius");
if (openButton)
openButton.setStyle("cornerRadius", cr);
if (textInput)
textInput.setStyle("cornerRadius", cr); */
}
}
/**
* @private
*/
override public function styleChanged(styleProp:String):void
{
var allStyles:Boolean = !styleProp || styleProp == "styleName";
super.styleChanged(styleProp);
if (allStyles || styleProp.indexOf("padding") == 0)
{
paddingChanged = true;
invalidateProperties();
}
if (allStyles || styleProp == "cornerRadius")
{
cornerRadiusChanged = true;
invalidateProperties();
}
}
/**
* @private
*/
override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
{
super.updateDisplayList(unscaledWidth, unscaledHeight);
}
]]>
</fx:Script>
<s:states>
<s:State name="normal" />
<s:State name="open" />
<s:State name="disabled" />
</s:states>
<!---
The PopUpAnchor control that opens the drop-down list.
<p>In a custom skin class that uses transitions, set the
<code>itemDestructionPolicy</code> property to <code>never</code>.</p>
-->
<s:PopUpAnchor id="popUp" displayPopUp.normal="false" displayPopUp.open="true" includeIn="open"
left="0" right="0" top="0" bottom="0" itemDestructionPolicy="auto"
popUpPosition="below" popUpWidthMatchesAnchorWidth="true">
<mx:Tree id="tree" labelField="@label"/>
</s:PopUpAnchor>
<!--- The default skin is ComboBoxButtonSkin.
@copy spark.components.supportClasses.DropDownListBase#openButton
@see spark.skins.spark.ComboBoxButtonSkin -->
<s:Button id="openButton" width="19" right="0" top="0" bottom="0" focusEnabled="false"
skinClass="spark.skins.spark.ComboBoxButtonSkin" tabEnabled="false" />
<!--- @copy spark.components.ComboBox#textInput -->
<s:TextInput id="textInput" enabled.disabled="false"
left="0" right="18" top="0" bottom="0"
skinClass="spark.skins.spark.ComboBoxTextInputSkin"/>
</s:SparkSkin>
3.0版本的
package com.webgriffe.components
{
import mx.controls.ComboBox;
import mx.controls.Tree;
import mx.core.ClassFactory;
import mx.events.DropdownEvent;
import mx.events.ListEvent;
public class TreeComboBox extends ComboBox
{
// -------------------------------------------------------------------------
//
// Properties
//
// -------------------------------------------------------------------------
// ----------------------------
// ddFactory
// ----------------------------
private var _ddFactory:ClassFactory;
private function get ddFactory():ClassFactory
{
if (_ddFactory == null)
{
_ddFactory = new ClassFactory();
_ddFactory.generator = TreeComboBoxRenderer;
_ddFactory.properties = {
width:this.width,
height:this._treeHeight,
outerDocument:this
};
}
return _ddFactory;
}
// ----------------------------
// treeHeight
// ----------------------------
private var _treeHeight:Number;
public function get treeHeight():Number
{
return _treeHeight;
}
public function set treeHeight(value:Number):void
{
this._treeHeight = value;
ddFactory.properties["height"] = this._treeHeight;
}
// ----------------------------
// treeSelectedItem
// ----------------------------
public var treeSelectedItem:Object;
// -------------------------------------------------------------------------
//
// Constructor
//
// -------------------------------------------------------------------------
public function TreeComboBox()
{
super();
this.dropdownFactory = ddFactory;
this.addEventListener(DropdownEvent.OPEN, onComboOpen);
}
// -------------------------------------------------------------------------
//
// Handlers
//
// -------------------------------------------------------------------------
private function onComboOpen(event:DropdownEvent):void
{
var tree:TreeComboBoxRenderer = dropdown as TreeComboBoxRenderer;
if (treeSelectedItem)
{
tree.expandParents(treeSelectedItem);
tree.selectNode(treeSelectedItem);
}
else
{
tree.expandItem(dataProvider.getItemAt(0), true);
}
}
// -------------------------------------------------------------------------
//
// Overridden methods
//
// -------------------------------------------------------------------------
/**
* Ovverride to avoid root node label being displayed as combo text when
* closing the combo box.
*/
override protected function updateDisplayList(unscaledWidth:Number,
unscaledHeight:Number):void
{
super.updateDisplayList(unscaledWidth, unscaledHeight);
if(dropdown && treeSelectedItem && treeSelectedItem[labelField] != null)
{
text = treeSelectedItem[labelField];
}
}
// -------------------------------------------------------------------------
//
// Other functions
//
// -------------------------------------------------------------------------
public function updateLabel(selectedItem:Object):void
{
if (selectedItem)
{
treeSelectedItem = selectedItem;
text = treeSelectedItem[labelField];
}
}
}
}
package com.webgriffe.components
{
import mx.controls.Tree;
import mx.events.ListEvent;
public class TreeComboBoxRenderer extends Tree
{
// -------------------------------------------------------------------------
//
// Properties
//
// -------------------------------------------------------------------------
[Bindable]
public var outerDocument:TreeComboBox;
// -------------------------------------------------------------------------
//
// Constructor
//
// -------------------------------------------------------------------------
public function TreeComboBoxRenderer()
{
super();
this.addEventListener(ListEvent.CHANGE, onSelectionChanged);
}
// -------------------------------------------------------------------------
//
// Handlers
//
// -------------------------------------------------------------------------
private function onSelectionChanged(event:ListEvent):void
{
outerDocument.updateLabel(event.currentTarget.selectedItem);
}
// -------------------------------------------------------------------------
//
// Other methods
//
// -------------------------------------------------------------------------
public function expandParents(node:Object):void
{
if (node && !isItemOpen(node))
{
expandItem(node, true);
expandParents(node.parent());
}
}
public function selectNode(node:Object):void
{
selectedItem = node;
var idx:int = getItemIndex(selectedItem);
scrollToIndex(idx);
}
}
}