Flex: обновление элемента управления Tree - PullRequest
6 голосов
/ 06 января 2009

У меня есть древовидный элемент управления с флажками, который использует элемент управления http://www.sephiroth.it/file_detail.php?id=151#

Каким-то образом я не могу заставить элемент управления обновляться, когда я изменяю dataProvider (то есть, нажимая флажок), единственный способ получить его для обновления - использовать полосу прокрутки. Как заставить обновление? Я перепробовал все возможные методы, которые я могу выяснить? (см. обновление ниже)

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

package offerta.monkeywrench.components
{

    import offerta.monkeywrench.components.componentClasses.TreeCheckBoxItemRenderer;

    import mx.collections.ArrayCollection;

    import mx.events.TreeEvent;

    public class WatchTree extends TreeCheckBox
    {

        public var idProperty:String;

        public var watchFactory:Function;

        private var _wSet:Boolean = false;

        /* clientId: */

        private var _clientId:String;

        [Bindable]
        public function get clientId():String
        {
            return _clientId;
        }

        public function set clientId(value:String):void
        {
            this._clientId = value;
        }

        /* //clientId */

        /* watching: */

        private var _watching:ArrayCollection;

        [Bindable]
        public function set watching(value:ArrayCollection):void
        {
            this._watching = value;
        }

        public function get watching():ArrayCollection
        {
            return this._watching;    
        }

        /* //watching */

        override public function initialize() :void
        {
            super.initialize();
            addEventListener("itemCheck", onItemCheck, false, 0, true);
        }

        private function isWatching(id:String):Boolean
        {
            for each(var w:Object in this._watching)
            {
                if(w[this.idProperty]==id) return true;
            }
            return false;
        }

        private function onItemCheck(event:TreeEvent):void
        {
            var item:Object = event.item as Object;
            var currentValue:uint = (event.itemRenderer as TreeCheckBoxItemRenderer).checkBox.checkState;
            if(item.children==null)
            {
                currentValue==2 ? addWatch(item.Id) : removeWatch(item.Id);
            }
            else
            {
                for each(var x:Object in item.children)
                {
                    currentValue==2 ? addWatch(x.Id) : removeWatch(x.Id);
                }
            }
            updateParents(item, currentValue);
            updateChilds(item, currentValue);
            this.dataProvider.refresh();
            super.invalidateProperties();
            super.invalidateDisplayList();
            super.updateDisplayList(this.unscaledWidth, this.unscaledHeight);
        }

        private function updateParents(item:Object, value:uint):void
        {
            var checkValue:String = (value == ( 1 << 1 | 2 << 1 ) ? "2" : value == ( 1 << 1 ) ? "1" : "0");
            var parentNode:Object = item.parent;
            if(parentNode)
            {
                for each(var x:Object in parentNode.children)
                {
                    if(x.checked != checkValue)
                    {
                        checkValue = "2"
                    }
                }
                parentNode.checked = checkValue;
                updateParents(parentNode, value);
            }
        }

        private function updateChilds(item:Object, value:uint):void
        {
            var middle:Boolean = (value&2<<1)==(2<<1);

            if(item.children!=null && item.children.length>0&&!middle)
            {
                for each(var x:Object in item.children)
                {
                    x.checked = value == (1<<1|2<<1) ? "2" : value==(1<<1) ? "1" : "0";
                    updateChilds(x, value);
                }
            }
        }

        private function addWatch(id:String):void
        {
            if(isWatching(id)) return;
            this._watching.addItem(this.watchFactory(id, this.clientId));
        }

        private function removeWatch(id:String):void
        {
            for(var i:int=0, n:int=this._watching.length; i<n; ++i)
            {
                if(this._watching[i][this.idProperty]==id)
                {
                    this._watching.removeItemAt(i);
                    return;
                }
            }
        }

        public function update(__watching:ArrayCollection, __clientId:String):void
        {
            clientId = __clientId;
            watching = __watching;
            if(this.dataProvider!=null)
            {
                var ws:ArrayCollection = ArrayCollection(this.dataProvider);
                for each(var group:Object in ws)
                {
                    var count:int = 0;
                    for each(var child:Object in group.children)
                    {
                        if(isWatching(child.Id))
                        {
                            child.checked = "1";
                            count++;
                        }
                    }
                    group.checked = (count==0 ? "0" : (count==group.children.length ? "1" : "2"));
                }
                this._wSet = false;

                var dp:ArrayCollection = ArrayCollection(this.dataProvider);
                dp.refresh();
                super.invalidateProperties();
                super.invalidateDisplayList();
                super.updateDisplayList(this.unscaledWidth, this.unscaledHeight);

                //scroll up the list???

                //collapse? (doesn't work)
                this.expandItem(null, false);
            }
        }

    }       

}

Ответы [ 3 ]

20 голосов
/ 06 января 2009

Я нашел элемент управления Tree немного обидчивым во Flex. В итоге я заставил перерисовку отключить dataProvider и заново подключить его, а затем принудительно проверить, что-то вроде этого:

private function forceRedraw(tree:Tree, dataProvider:Object):void
{
    var scrollPosition:Number = tree.verticalScrollPosition;
    var openItems:Object = tree.openItems;
    tree.dataProvider = dataProvider;
    tree.openItems = openItems;
    tree.validateNow();
    tree.verticalScrollPosition = scrollPosition;
}

Полагаю, это случайно отвечает на вторую часть вашего вопроса, так как все, что вам нужно сделать, это обнулить коллекцию openItems и установить verticalScrollPosition в 0.

1 голос
/ 09 марта 2009

У вас может быть другая проблема: всякий раз, когда вы проверяете элемент, дерево прокручивается вверх, и это просто раздражает. Чтобы решить эту проблему, вы должны обновить файл TreeCheckBox.as следующим образом: в функции checkHandler: приватная функция checkHandler (событие: TreeEvent): void;

комментировать commitProperties (); позвонить.

Теперь все должно работать хорошо.

Приветствие.

0 голосов
/ 07 января 2009

У меня была небольшая проблема с этим решением, var scrollPosition: Number = tree.verticalScrollPosition; постоянно 0 ??

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...