开发者

Flex 4: mx|tree - how can i disable items selection?

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:

  1. two states: item and root_item.

  2. 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(the开发者_Go百科XML.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

itemClick="tree_itemClickHandler(event)"

Then in the event handler you can cancel the itemClick event

protected function tree_itemClickHandler(event:ListEvent):void
{
    tree.selectedItem = null;
    event.preventDefault();
}

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:

<s:states>
    <s:State name="normal" basedOn="{data.@state}"/>
    <s:State name="hovered" basedOn="{data.@state}"/>
    <s:State name="selected" basedOn="{data.@state}"/>
    <s:State name="root_item" />            
    <s:State name="item" />
</s:states>

Then regardless of the default state that is sent by the parent list the display will be based upon what is in your data.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜