Flex 4: mx | tree - как я могу отключить выбор элементов? - PullRequest
1 голос
/ 09 февраля 2011

Я хочу создать дерево, в котором его дочерние узлы содержат определенные компоненты flex, которые я создал. Я переопределяю ItemRenderer по умолчанию для достижения этой цели.

В моем ItemRenderer у меня есть:

  1. два состояния: item и root_item.

  2. функция, которая выполняется после завершения создания, которая с использованием данных проверяет правильное состояние, в котором должен находиться этот компонент, и переводит currentState в желаемое состояние.

Моя проблема в том, что как только пользователь нажимает на любой из элементов, он автоматически переключается на первое состояние, которое портит все.

как вообще отключить выбор элементов? конечно, я хочу, чтобы пользователь мог проходить вверх и вниз по деревьям, но не выбирать элементы.

спасибо!

обновление

Элемент изменяет состояния при наведении, поэтому я отключаю выбор элементов или каким-то образом предотвращаю изменение состояния при наведении.

еще одно обновление

это мой код:

основной 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>

как вы можете видеть здесь, я пытался предотвратить и itemRollover, и itemClick, но это не решило мою проблему.

это 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>

1 Ответ

2 голосов
/ 09 февраля 2011

Вы можете добавить обработчик событий в дерево для события itemClick

itemClick="tree_itemClickHandler(event)"

Затем в обработчике события вы можете отменить событие itemClick

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

Обновление:

Средство визуализации элементов имеет 3 состояния по умолчанию: нормальное, зависание и выбрано. Вам нужно использовать basedOn с 3 состояниями по умолчанию для ссылки на ваши пользовательские состояния. В идеале вы хотели бы, чтобы в ваших данных было указано состояние, чтобы вы могли избежать всей работы, которую вы выполняете в init (). Это также позволит вам привязать basedOn к состоянию ваших данных как таковое:

<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>

Тогда независимо от состояния по умолчанию, отправляемого родительским списком, отображение будет основываться на том, что находится в ваших данных.

...