Как переопределить элементы управления дочерними узлами в элементе управления Flex Tree

В настоящее время я разрабатываю динамическую диаграмму LineChart в FLEX 4. Я реализую элемент управления Tree рядом с моей LineChart, который будет фильтровать поставщик данных LineChart и ряды строк. Древовидный элемент управления имеет несколько ветвей и, в конечном итоге, 5 дочерних элементов (конечных узлов) в нижней части последней ветви.

Мне нужно, чтобы листовой узел / дочерние элементы отображались в виде флажков внутри элемента управления деревом. Насколько я понимаю, для этого потребуются переопределения в классе TreeItemRenderer. Здесь я немного не понимаю, как это реализовать.

В настоящее время я могу различать лист и ветки с помощью этого кода в моем основном компоненте MXML. Я добавил это, потому что это может быть полезно для некоторых начинающих разработчиков FLEX, таких как я, которые не могут легко найти эту функциональность, хорошо задокументированную:

            private function treeClick(e:ListEvent):void {

            _selectedItem = Tree(e.currentTarget).selectedItem;

            if(mainTree.dataDescriptor.isBranch(_selectedItem)) {
                Alert.show('branch click');
            }
            else {
                Alert.show('leaf node click');
            }

        }

Я смотрю на класс переопределения TreeItemRenderer из следующего примера здесь:

В этом примере они переопределяют суперфункцию createChildden, добавляя флажки к элементу управления деревом.

У меня вопрос: Могу ли я переопределить функцию createChildren непосредственно в моем компоненте MXML и не использовать весь файл класса для переопределения этой функции? Должен ли я для этого заново изобретать колесо?

Кроме того, как я могу различить, что мой treeItem является листовым узлом, а не родительским, в функции переопределения? Я хочу добавить флажки только к листовым узлам, как я могу различать? В следующем примере флажки добавляются ко всем ветвям и конечным узлам, но я хочу добавить флажки только к конечным узлам / дочерним узлам. Как бы вы к этому подойти?

        override protected function createChildren( ): void
        {
            super.createChildren( );
            if( !_checkbox )
            {
                _checkbox = new CheckBoxExtended( );
                _checkbox.allow3StateForUser = false;
                _checkbox.addEventListener( MouseEvent.CLICK, onCheckboxClick );
                addChild( _checkbox );
            }
        }

Вот XML, с которым я работаю:

    <mx:XMLList id="treeData">
    <node label="DAIX">
        <node label="Account 1">
            <node label="Premise 1">
                <node label="Device 1" oid="31" isChecked="false">
                </node>
                <node label="Device 2" oid="32" isChecked="false">
                </node>
            </node>
            <node label="Premise 2">
                <node label="Device 1" oid="41" isChecked="false">
                </node>
                <node label="Device 2" oid="42" isChecked="false">
                </node>                 
            </node>
        </node>
        <node label="Account 2">
            <node label="Premise 1">
                <node label="Device 1" oid="31" isChecked="false">
                </node>
                <node label="Device 2" oid="32" isChecked="false">
                </node>             
            </node>
            <node label="Premise 2">
                <node label="Device 1" oid="31" isChecked="false">
                </node>
                <node label="Device 2" oid="32" isChecked="false">
                </node>                 
            </node>
        </node>
    </node>    
</mx:XMLList>

Вот мой тег дерева:

<mx:Tree id="mainTree" dataProvider="{treeData}" itemRenderer="TreeCheckBoxItemRenderer" labelField="@label" showRoot="false" width="100%" height="100%" itemClick="treeClick(event)" />

person D3vtr0n    schedule 20.08.2010    source источник
comment
Если вы выполняете компонент mxml, это эквивалентно созданию подкласса его корневого элемента. Реализация функции переопределения отменяет ее для этого класса. Если вам нужно что-то переопределить для вложенного компонента, вы должны сделать его отдельным компонентом.   -  person alxx    schedule 21.08.2010
comment
Хорошо, мои элементы управления LineChart и Tree находятся в контейнере Panel. Если я использую в своем MXML функцию переопределения, она хочет переопределить функцию createChildren в Panel. Могу ли я указать способ переопределения элемента управления "Дерево" вместо моей панели?   -  person D3vtr0n    schedule 21.08.2010


Ответы (1)


Вот что я бы сделал: создайте средство визуализации элементов, производное от TreeItemRender, в качестве компонента MXML и включите свой флажок в MXML, а затем переопределите средство установки для listData. В вашем переопределенном методе сделайте что-то вроде этого:

РЕДАКТИРОВАТЬ: добавлен окружающий MXML (обратите внимание, что MXML в значительной степени является тем, что FB 4 генерирует по умолчанию при создании нового средства визуализации элементов дерева, и что я не тестировал это в дереве).

EDIT2: добавлен код для перемещения отмеченного состояния назад и вперед между компонентом и данными.

<fx:Script>
    <![CDATA[
        import mx.controls.treeClasses.TreeListData;

        override public function set listData(value:BaseListData):void
        {
            super.listData = value
            this.myCheckbox.visible = !(value as TreeListData).hasChildren;
            this.myCheckbox.includeInLayout = !(value as TreeListData).hasChildren;
        }

        override public function set data(value:Object):void {
            super.data = value;

            this.myCheckbox.selected = this.data.isChecked;
        }

        private function onCheckboxChange(e:Event):void {
            this.data.isChecked = this.myCheckbox.selected;
        }
    ]]>
</fx:Script>
<s:states>
    <s:State name="normal" />      
    <s:State name="hovered" />
    <s:State name="selected" />
</s:states>
<s:HGroup left="0" right="0" top="0" bottom="0" verticalAlign="middle">
    <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:CheckBox id="myCheckbox" change="onCheckboxChange(event)"/>
    <s:Label id="labelField" text="{treeListData.label}" paddingTop="2"/>
</s:HGroup>

person Wade Mueller    schedule 20.08.2010
comment
^ Я немного сбит с толку, почему createChildren не используется здесь в вашем коде? когда вы говорите включить свой флажок в MXML, вы имеете в виду флажок в режиме разработки / разметки? в самом макете MXML элемента управления Tree? или вы имеете в виду, включить его в переопределение createChildren, динамически, в код AS рендеринга / переопределения? Инстинкт программиста удерживает меня от дизайна и верстки, и я хочу чрезмерно усложнять вещи, поэтому прошу прощения за не совсем понимание. - person D3vtr0n; 23.08.2010
comment
Я добавил окружающий MXML в свой пример выше. Я понимаю ваш инстинкт держаться подальше от MXML и держать вещи в коде, но с рендерерами элементов все становится сложно, потому что рендереры повторно используются. Это означает, что вы не всегда можете полагаться на такие вещи, как createChildren, чтобы их вызвали, когда вы этого ожидаете. Единственное, что действительно надежно, - это установщики данных и listData, поэтому обычно рекомендуется настраивать состояние вашего средства визуализации с помощью этих методов. Надеюсь, это поможет. - person Wade Mueller; 23.08.2010
comment
Это сработало как чемпион! Единственное изменение, которое требовалось в вашем коде, - это ссылка на пространство имен: [import mx.controls.listClasses.BaseListData;]. Как красиво!! Это потрясающе, и я бы дал вам 1000 очков, если бы мог! Ура, чувак. Я тебе должен. - person D3vtr0n; 25.08.2010
comment
^ Как бы установить для свойства selected флажка значение false? Если вы попробуете что-то вроде этого: _selectedItem = Tree (e.currentTarget) .selectedItem; _selectedItem.selected = false; он перерисовывает дерево, теряет флажок и использует значки по умолчанию и создает новый листовой узел с false в качестве текста метки. Может быть, мне не следует использовать e.currentTarget, чтобы переключать флажок? Добавьте эти две строки в событие щелчка, и вы поймете, что я имею в виду! Отличный пост, несмотря ни на что, вау! - person D3vtr0n; 25.08.2010
comment
А теперь самое интересное. Чтобы сделать ваши флажки полезными, вам нужно добавить поле к элементам в вашем dataProvider для хранения логического значения, назовем его isChecked. Затем вы можете привязать выбранное свойство в вашем флажке к значению данных, примерно так: ‹s: Checkbox ... selected = {data.isChecked} /› Затем вы можете просто обратиться к dataProvider, чтобы определить, какие из них выбраны. - person Wade Mueller; 25.08.2010
comment
Я отредактировал исходный вопрос, чтобы добавить свой XMLList (данные) и свой тег дерева. Я также сейчас использую это в рендерере: ‹s: CheckBox id = myCheckbox selected = {data.isChecked} /› Когда дерево загружается, все флажки отмечены. Я могу легко их снять, но потом не могу их перепроверить. Мои данные / узлы неверны? Я замечаю, что когда я пытаюсь еще раз установить флажок для пустого флажка, он ненадолго появляется, а затем исчезает, как будто элемент управления Tree переопределяет его или перерисовывает его пустым. - person D3vtr0n; 25.08.2010
comment
Также я не понимаю, почему дерево загружается с флажками selected = true, когда XML-элемент isChecked = false ??? Я думаю, это игнорирует мой XML? - person D3vtr0n; 25.08.2010
comment
Я также заметил, что во время выполнения получаю предупреждения о привязке к свойству isChecked ...... предупреждение: невозможно привязать к свойству isChecked в классе XML (класс не является IEventDispatcher) - person D3vtr0n; 25.08.2010
comment
Я добавил код, чтобы показать, как перемещать данные между компонентами. Это устранит ваше предупреждение. Это НЕ решит вашу проблему, если все они будут отображаться как изначально проверенные. Это вызвано вашим xml, потому что isChecked не анализируется как логическое значение, он, вероятно, проходит как строка и приводится к логическому значению, что означает, что false считывается ненулевой строкой и, следовательно, считается истинным. Я бы попробовал изменить false на 0 и посмотреть, что произойдет. Но никаких гарантий на этот счет. :) - person Wade Mueller; 25.08.2010
comment
Если я установил isChecked = 0 в своем XML, я получаю сообщение об ошибке. Мне нужно использовать isChecked = 0, и я все равно получаю предупреждение о привязке свойства. Кроме того, с обновленным кодом (Edit 2) я ухудшаю поведение узлов. Если вы разворачиваете / свертываете узлы Premise, флажки удаляются, а все оставшиеся флажки проверяются повторно. Он также помещает false в запись подузла и изменяет значки. Это становится действительно круто. Попробуйте и убедитесь, что это странно. - person D3vtr0n; 25.08.2010
comment
Вы удалили selected = {data.isChecked} из своего флажка? Если нет, то нужно. Это должно позаботиться о вашем предупреждении, поскольку вы больше ни к чему не привязаны, а также объяснило бы некоторые из ваших странных действий. - person Wade Mueller; 25.08.2010