2009-01-06 7 views
6

tengo un control de árbol con casillas de verificación que utiliza el control de http://www.sephiroth.it/file_detail.php?id=151#Flex: La actualización de un control de árbol

De alguna manera no puedo conseguir el control de actualizar cuando cambio la dataProvider (es decir, haciendo clic en una casilla de verificación) del La única forma en que puedo conseguir que actualice es usar la barra de desplazamiento. ¿Cómo fuerzo la actualización? ¿He intentado todos los métodos posibles que puedo descifrar? (ver la actualización a continuación)

También, ¿cómo puedo restablecer el árbol (collpando todos los nodos, desplazarse hacia la parte superior en un árbol grande)?

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); 
      } 
     } 

    }  

} 

Respuesta

20

He encontrado el control Tree un poco sensible en Flex. La forma en que terminó forzando un redibujado era de desconectar y volver a conectar el dataProvider que, a continuación, forzar la validación, algo un poco como esto:

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

supongo que esto responde a dicho sea de paso la segunda parte de su pregunta ya que todo lo que había lo que hay que hacer es anular la colección openItems y establecer verticalScrollPosition en 0.

+0

Gracias! ¡Eres mi héroe hoy! –

+0

2 años abajo, ¡y esto sigue siendo útil! ¡increíble! –

+1

@RoopeshShenoy: ¡Haz que 3! – Viktor

0

He tenido algún problema menor con esta solución, var scrollPosition: Number = tree.verticalScrollPosition; es constantemente 0?

+0

Depende de la cantidad de elementos que tenga en el árbol. ¿Tiene un árbol grande que se muestra y se ha desplazado realmente cuando está tratando de forzar un redibujado? – inferis

+0

Sí, incluso cuando se desplaza el Árbol, verticalScrollPosition sigue siendo 0. –

1

Puede que tenga otro problema: cada vez que comprueba un elemento, el árbol se desplaza hacia la parte superior y esto es simplemente molesto. Para resolver este problema, debe actualizar el archivo TreeCheckBox.as de esta manera: en la función checkHandler: checkHandler de función privada (evento: TreeEvent): void;

comment the commitProperties(); llamada.

Ahora debería funcionar bien.

Saludos.

Cuestiones relacionadas