I want to create a tree that it's child nodes contain specific flex components that I created. I override the default ItemRenderer to achieve this.
In my ItemRenderer i have:
two states:
item
androot_item
.a function that executes after creation complete that using the data validates the proper state that this component should be in and changes the
currentState
to the desired state.
My problem is that once the user clicks on any of the elements, it changes automatically to the first state which mess things up.
how can I disable items selection at all ? of course I want the user to be able to drill up and down the trees but not to select the items.
thanks!
update
The Item changes states on hover effect, so or I disable items selection or somehow i prevent the hover effect from changing the state.
another update
this is my code:
the main TreeTest.xml:
<?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" autoLayout="false" minHeight="600">
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
<fx:XML id="treeData">
<node label="notifications">
<node label="Winnings" is_root="yes">
<node label="winner"/>
</node>
<node label="Challenges" is_root="yes">
</node>
<node label="Achievements" is_root="yes">
</node>
<node label="Lucky charms" is_root="yes">
</node>
<node label="Friend requests" is_root="yes">
</node>
</node>
</fx:XML>
</fx:Declarations>
<fx:Script>
<![CDATA[
import mx.controls.Alert;
import mx.controls.listClasses.ListBase;
import mx.events.ListEvent;
protected function tree_itemClickHandler(event:ListEvent):void
{
tree.selectedItem = null;
event.preventDefault();
}
protected function tree_itemRollOverHandler(event:ListEvent):void {
event.preventDefault();
}
]]>
</fx:Script>
<mx:Tree id="tree" itemRollOver="tree_itemRollOverHandler(event)" itemClick="tree_itemClickHandler(event)" dataProvider="{treeData}" folderOpenIcon="{null}" folderClosedIcon="{null}" defaultLeafIcon="{null}" width="1024" height="768" labelField="@label" itemRenderer="TreeItemRenderer" showRoot="false" allowMultipleSelection="false" allowDragSelection="false"/>
</s:Application>
as you can see here I tried to prevent both itemRollover and itemClick but it did not resolve my problem.
this is the TreeItemRenderer.xml:
<?xml version="1.0" encoding="utf-8"?>
<s:MXTreeItemRenderer xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx" creationComplete="init()">
<s:states>
<s:State name="root_item" />
<s:State name="item" />
</s:states>
<fx:Script>
<![CDATA[
import com.flexer.Debug;
import mx.binding.utils.ChangeWatcher;
import mx.controls.Alert;
import mx.events.StateChangeEvent;
private function _stateChangeEventHandler(e:StateChangeEvent):void {
Alert.show("state changed to " + e.target.currentState);
}
private function init():void {
var theXML:XMLList = XMLList(this.data);
var theState:String =( theXML.attribute("is_root") == "yes" ? "root_item" : "item");
this.currentState=theState;
this.addEventListener(StateChangeEvent.CURRENT_STATE_CHANGE,this._stateChangeEventHandler);
// Alert.show(theXML.attribute("is_root"));
// Alert.show(theXML.attribute("label") + (theXML.attribute("is_root") == "yes" ? "true" : "false"));
}
]]>
</fx:Script>
<s:HGroup left="0" right="0" top="0" bottom="0" verticalAlign="middle" includeIn="root_item">
<s:Rect id="indentationSpacer" width="{treeListData.indent}" percentHeight="100" alpha="0">
<s:fill>
<s:SolidColor color="0xFFFFFF" />
</s:fill>
</s:Rect>
<s:Group id="disclosureGroup">
<s:BitmapImage source="{treeListData.disclosureIcon}" visible="{treeListData.hasChildren}" />
</s:Group>
<s:BitmapImage source="{treeListData.icon}" />
<s:Label id="labelField" text="{treeListData.label}" paddingTop="2"/>
</s:HGroup>
</s:MXTreeItemRenderer>
You can add an event handler to the tree for the itemClick event
Then in the event handler you can cancel the itemClick event
Update:
The item renderer has 3 default states: normal, hovered, and selected. You need to use basedOn with the 3 default states to reference your custom states. Ideally you would want the state in your data so you can avoid all of the work you're doing in init(). It would also allow you to bind basedOn to the state of your data as such:
Then regardless of the default state that is sent by the parent list the display will be based upon what is in your data.