由于项目需要,我们需要一个自定义的ComboBox,它可以让其中的一些选项根据上下文环境变灰(不可选)。由于Flex自身并不提供这样的控件,因此就开始研究啊研究。
首先google一下,发现最网络上这个方面的讨论很少,只有在Alex的blog上找到了一条有关于不可选的List,而具体改list如何应用到ComboBox中去,其实并不是件容易的事情。
于是就自己动手了。具体如何实现就不详细解释,直接看代码:
注:如果访问demo有问题,那么新开一个浏览器,输入http://williscai.blogbus.com,访问后再输入http://williscai.blogbus.com/files/12209491200.swf,即可。blogbus的放盗链真是麻烦,不能直接从这里访问。
//Demo
<?xml version="1.0"?>
<!-- DisabledComboBoxItemsTest.mxml -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" xmlns:cwmlib="com.cwmlib.controls.*">
<mx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
[Bindable]
private var dpFlat:ArrayCollection = new ArrayCollection([
{territory:"Dana Binn", enabled:true},
{territory:"Barbara Jennings", enabled:false},
{territory:"Joe Smith", enabled:false},
{territory:"Bethany Pittman", enabled:true},
{territory:"T.R. Smith", enabled:true},
{territory:"Alice Treu", enabled:false},
{territory:"Jane Grove", enabled:true}
]);
[Bindable]
private var dpxml:XML =
<regions>
<region territory="Dana Binn" enabled="false"/>
<region territory="Barbara Jennings" enabled="false"/>
<region territory="Joe Smith" enabled="false"/>
<region territory="Bethany Pittman" enabled="true"/>
<region territory="T.R. Smith" enabled="true"/>
<region territory="Alice Treu" enabled="true"/>
<region territory="Jane Grove" enabled="true"/>
</regions>;
]]>
</mx:Script>
<mx:VBox width="100%" height="100%">
<mx:Text text="DataProvider is ArrayCollection" fontWeight="bold"/>
<mx:HBox width="100%">
<cwmlib:DisabledList dataProvider="{dpFlat}" labelField="territory"/>
<cwmlib:DisabledComboBox dataProvider="{dpFlat}" labelField="territory"/>
</mx:HBox>
<mx:Text text="DataProvider is XML" fontWeight="bold"/>
<mx:HBox width="100%">
<cwmlib:DisabledList dataProvider="{dpxml.region}" labelField="@territory"/>
<cwmlib:DisabledComboBox dataProvider="{dpxml.region}" labelField="@territory"/>
</mx:HBox>
</mx:VBox>
</mx:Application>
//-------------------------------------------------------------------
//DisabledComboBox.as
package com.cwmlib.controls
{
/**
* DisabledComboBox.as
*
* Copyright (c) 2008 Weimin Cai
* All rights reserved.
*
* The source code is the copyrighted,
*
* Revision History
*
* June 18, 2008 Weimin Cai
*/
import mx.controls.ComboBox;
import mx.core.ClassFactory;
import mx.events.FlexEvent;
public class DisabledComboBox extends ComboBox
{
/**
* Constructor.
*/
public function DisabledComboBox()
{
super();
this.dropdownFactory = new ClassFactory(DisabledList);
this.itemRenderer = new ClassFactory(DisabledListItemRenderer);
}
/**
* @private
*/
override public function set dataProvider(value:Object):void
{
super.dataProvider = value;
moveToEnable();
}
private function moveToEnable():void {
var i:int = -1;
for each (var obj:Object in dataProvider) {
i++;
if (this.selectedIndex == -1) {
this.selectedIndex = 0;
}
if (i < this.selectedIndex) {
continue;
}
if (obj != null
&& ((obj is XML && obj.@enabled == 'false')
|| obj.enabled==false || obj.enabled=='false')){
if(i == this.selectedIndex){
this.selectedIndex++;
}
}
}
if (this.selectedIndex > i) {
this.selectedIndex = 0;
}
}
override public function initialize():void
{
this.toolTip = this.text;
if (initialized)
return;
createChildren();
super.initialize();
}
/**
* @private
* Make sure the drop-down width is the same as the rest of the ComboBox
*/
override protected function updateDisplayList(unscaledWidth:Number,
unscaledHeight:Number):void
{
super.updateDisplayList(unscaledWidth, unscaledHeight);
this.toolTip = this.text;
}
private function textInput_valueCommitHandler(event:FlexEvent):void
{
// update _text if textInput.text is changed programatically
super.text = textInput.text;
dispatchEvent(event);
}
private function textInput_enterHandler(event:FlexEvent):void
{
dispatchEvent(event);
dispatchEvent(new FlexEvent(FlexEvent.VALUE_COMMIT));
}
}
}
这里要解释的就一个函数moveToEnable(),该函数无非是当selectedIndex所在的item如果是enabled为false时,把selectedIndex自动往下移,知道碰到一个enabled为true的item。
//-------------------------------------------------------------------
//DisabledList.as
package com.cwmlib.controls
{
/**
* DisabledListr.as
*
* Copyright (c) 2008 Weimin Cai
* All rights reserved.
*
* The source code is the copyrighted,
*
* Revision History
*
* June 18, 2008 Weimin Cai
*/
import flash.events.MouseEvent;
import flash.events.KeyboardEvent;
import mx.core.ClassFactory;
import mx.controls.List;
import mx.controls.listClasses.IListItemRenderer;
import mx.controls.listClasses.ListItemRenderer;
public class DisabledList extends List
{
/**
* Constructor.
*/
public function DisabledList()
{
super();
this.itemRenderer = new ClassFactory(DisabledListItemRenderer);
}
/**
* Prevent mouse over handler when item is disabled.
*/
override protected function mouseOverHandler(event:MouseEvent):void
{
var item:IListItemRenderer = mouseEventToItemRenderer(event);
if (itemDisable(event)) {
// Disable selection.
} else {
super.mouseOverHandler(event);
}
}
/**
* Prevent mouse down handler when item is disabled.
*/
override protected function mouseDownHandler(event:MouseEvent):void {
if (itemDisable(event)) {
// Disable click.
return;
} else {
super.mouseDownHandler(event);
}
}
/**
* Prevent mouse up handler when item is disabled.
*/
override protected function mouseUpHandler(event:MouseEvent):void {
if (itemDisable(event)) {
// Disable click.
return;
} else {
super.mouseUpHandler(event);
}
}
/**
* Prevent mouse click handler when item is disabled.
*/
override protected function mouseClickHandler(event:MouseEvent):void {
if (itemDisable(event)) {
// Disable click.
return;
} else {
super.mouseClickHandler(event);
}
}
/**
* Prevent mouse double click handler when item is disabled.
*/
override protected function mouseDoubleClickHandler(event:MouseEvent):void {
if (itemDisable(event)) {
// Disable double click.
event.preventDefault();
} else {
super.mouseDoubleClickHandler(event);
}
}
/**
* Prevent mouse double click handler when item is disabled.
*/
override protected function keyDownHandler(event:KeyboardEvent):void {
event.stopPropagation();
// Disable key down event.
//super.keyDownHandler(event);
}
private function itemDisable(event:MouseEvent):Boolean {
var item:IListItemRenderer = mouseEventToItemRenderer(event);
if (item != null && item.data != null
&& ((item.data is XML && item.data.@enabled == 'false')
|| item.data.enabled==false || item.data.enabled=='false')
) {
return true;
} else {
return false;
}
}
}
}
解释:当鼠标或者键盘移动到一个enabled为false的item上是,屏蔽掉所有事件,让其不可选。具体要扩展或者定制,只需要修改itemDisable()这个函数的判断条件。
//-------------------------------------------------------------------
//DisabledListItemRenderer.as
package com.cwmlib.controls
{
/**
* DisabledListItemRenderer.as
*
* Copyright (c) 2008 Weimin Cai
* All rights reserved.
*
* The source code is the copyrighted,
*
* Revision History
*
* June 18, 2008 Weimin Cai
*/
import mx.controls.Label;
public class DisabledListItemRenderer extends Label
{
private var _enabled:Boolean = true;
/**
* Constructor.
*/
public function DisabledListItemRenderer()
{
super();
}
/**
* @private
*/
override public function set data(value:Object):void
{
if (value != null && ((value is XML && value.@enabled == 'false')
|| value.enabled==false || value.enabled=='false')){
this._enabled = false;
}else{
this._enabled = true;
}
super.data = value;
}
override protected function updateDisplayList(unscaledWidth:Number,
unscaledHeight:Number):void
{
super.updateDisplayList(unscaledWidth, unscaledHeight);
if (!this._enabled) {
textField.setColor(getStyle("disabledColor"));
}else{
textField.setColor(getStyle("color"));
}
}
}
}
评论