您的位置:首页 > 其它

Flex中带有三种状态CheckBox的Tree的实现

2012-05-15 17:08 525 查看
常常会用到带有3种状态CheckBox的树形组件,比如在权限管理中,或者是地区选择中等等,如下图:



不多说费话了,直接进入主题,看看如何实现。其实在Flex中,只用自己实现一个TreeItemRenderer就可以了,代码如下:




package com.robin

{


import flash.events.Event;


import flash.geom.Rectangle;




import mx.controls.CheckBox;


import mx.controls.treeClasses.TreeItemRenderer;


import mx.controls.treeClasses.TreeListData;


import mx.events.FlexEvent;






public class ThreeStatusCheckBoxTreeItemRenderer extends TreeItemRenderer

{


private static var _colorForThirdState:int = 0x37BEF8;


private static var _selectedField:String = "selected";




private var checkBox:CheckBox;






public function ThreeStatusCheckBoxTreeItemRenderer()

{


super();


}






override protected function createChildren():void

{


super.createChildren();


checkBox = new CheckBox();


addChild(checkBox);


checkBox.addEventListener(Event.CHANGE, changeHandler);


}






/**//**


* Initial data when component initialization


*


*/




override protected function commitProperties():void

{


super.commitProperties();




if (data && data.@[_selectedField] != null)

{


var s:int = int(data.@[_selectedField]);


var selected:Boolean = s > 0 ? true : false;


checkBox.selected = selected;




} else

{


checkBox.selected = false;


}


}






/**//**


* update dataProvider when user click CheckBox


*


*/




protected function changeHandler(event:Event):void

{




if (data && data.@[_selectedField] != null)

{


data.@[_selectedField] = checkBox.selected ? "1" : "0";


}




var listData:TreeListData = TreeListData(listData);




if (listData.hasChildren)

{


var item:XML = XML(listData.item);


handleAllChildren(item.children());


}


handleAllParents(listData.item.parent());


}






private function handleAllChildren(children:XMLList):void

{




for each (var item:XML in children)

{


item.@[_selectedField] = checkBox.selected ? "1" : "0";


var children:XMLList = item.children();




if (children.length() > 0)

{


handleAllChildren(children);


}


}


}






private function handleAllParents(parent:XML):void

{




if (parent != null)

{


var children:XMLList = parent.children();


var hasSelected1:Boolean = false;


var hasSelected2:Boolean = false;


var hasSelected0:Boolean = false;




for each (var item:XML in children)

{




if (int(item.@[_selectedField]) == 1)

{


hasSelected1 = true;


}




if (int(item.@[_selectedField]) == 2)

{


hasSelected2 = true;


}




if (int(item.@[_selectedField]) == 0)

{


hasSelected0 = true;


}


}




if (checkBox.selected == true)

{




if (!hasSelected0 && !hasSelected2)

{


parent.@[_selectedField] = "1";




} else

{


parent.@[_selectedField] = "2";


}




} else

{




if (!hasSelected1 && !hasSelected2)

{


parent.@[_selectedField] = "0";




} else

{


parent.@[_selectedField] = "2";


}


}


handleAllParents(parent.parent());


}


}






/**//**


* reset itemRenderer's width


*/




override protected function measure():void

{


super.measure();


measuredWidth += checkBox.getExplicitOrMeasuredWidth();


}






/**//**


* re-assign layout for tree, move lable to right


* @param unscaledWidth


* @param unscaledHeight


*/




override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void

{


super.updateDisplayList(unscaledWidth, unscaledHeight);


var startx:Number = data ? TreeListData(listData).indent : 0;






if (disclosureIcon)

{


disclosureIcon.x = startx;


startx = disclosureIcon.x + disclosureIcon.width;


disclosureIcon.setActualSize(disclosureIcon.width, disclosureIcon.height);


disclosureIcon.visible = data ? TreeListData(listData).hasChildren : false;


}




if (icon)

{


icon.x = startx;


startx = icon.x + icon.measuredWidth;


icon.setActualSize(icon.measuredWidth, icon.measuredHeight);


}


checkBox.move(startx, (unscaledHeight - checkBox.height) / 2);


label.x = startx + checkBox.getExplicitOrMeasuredWidth();




var node:XML = data as XML;




if (int(node.@[_selectedField]) == 2)

{


fillCheckBox(true);




} else

{


fillCheckBox(false);


}




}






/**//**


* re-draw check box for the third state


* @param isFill


*/




private function fillCheckBox(isFill:Boolean):void

{


checkBox.validateNow();


checkBox.graphics.clear();




if (isFill)

{


var myRect:Rectangle = checkBox.getBounds(checkBox);


checkBox.graphics.beginFill(_colorForThirdState, 1);


checkBox.graphics.drawRoundRect(myRect.x, myRect.y, myRect.width, myRect.height, 1, 0x00FF00);


checkBox.graphics.endFill();


}


}






}


}

然后在tree组件中使用这个renderer就可以了。


<?xml version="1.0" encoding="utf-8"?>


<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"


xmlns:s="library://ns.adobe.com/flex/spark"


xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600" xmlns:robin="com.robin.*">


<fx:Declarations>


<fx:XMLList id="treeData">


<node name = "ShangHai" type="ROOT" selected ="1">


<node name = "HuangPu" type="NODE" selected = "1">


<node name = "A" type="NODE" selected = "1" />


<node name = "B" type="NODE" selected = "1" />


</node>


<node name = "PuDong" type="NODE" selected = "1"/>


</node>


<node name = "Beijing" type="ROOT" selected = "2">


<node name = "HaiDian" type="NODE" selected = "0"/>


<node name = "ChaoYang" type="NODE" selected = "1"/>


</node>


</fx:XMLList>


</fx:Declarations>


<fx:Script>


<![CDATA[




protected function getCurrentData_clickHandler(event:MouseEvent):void

{


currentText.text = String(treeData);


}


]]>


</fx:Script>




<mx:Tree x = "0" y = "0" width = "232" height = "285" itemRenderer = "com.robin.ThreeStatusCheckBoxTreeItemRenderer" labelField = "@name" dataProvider = "{treeData}"/>


<s:Button x = "43" y = "293" label = "Get Current Data" id = "getCurrentData" click = "getCurrentData_clickHandler(event)"/>


<s:TextArea x = "253" y = "0" width = "459" height = "285" id = "currentText"/>


</s:Application>



就是这么简单!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: