3 Replies Latest reply on Oct 14, 2010 9:14 AM by vmvmvmvmvm

    Forcing State to Refresh in an ItemRenderer during a Drag and Drop

    vmvmvmvmvm

      Following the excellent dicussion here

      http://forums.adobe.com/message/2091088

       

      I override getCurrentRendererState so that my itemRender can reflect the new states that I've declared. I want the state to update during a drag and drop operation within a Tree control. Within a dragOverHandler, I set a boolean property on the itemRenderer (which causes the return value of getCurrentRendererState to change). Nothing happens during the drag since getCurrentRendererState isn't being called by...

       

      How can I force the itemRenderer to refresh its state? When I just mouse over the item renderer, I see that 'getCurrentRendererState' is being invoked and the state updates. I've tried invoking invalidateDisplayList, invalidateProperties, invalidateSize, validateNow but they seem to be on hold during a drag operation.

       

      Any insights?

        • 1. Re: Forcing State to Refresh in an ItemRenderer during a Drag and Drop
          vmvmvmvmvm Level 1

          Bump. Still struggling with this... hope to find an answer soon :-(

          • 2. Re: Forcing State to Refresh in an ItemRenderer during a Drag and Drop
            leecoltrane

            After you change something that might affect your renderer's state, you need to call:

              setCurrentState(getCurrentRendererState(), (mx_internal::playTransitions as Boolean)); 
            
            
            

            Unfortunately, state can depend on many things, and it's difficult to make sure that you make this call every single time you change any of those things that may ultimately affect a renderer's self-determined state.  In fact, if you're trying to write extensible code, it's impossible to implement it this way, because you have no way of knowing what properties will affect state in some future implementation that someone might come up with.

             

            So... instead of calling the above directly, I suggest that you simply override commitProperties() and do it there - like this:

              override protected function commitProperties():void 
              {
                setCurrentState(getCurrentRendererState(), (mx_internal::playTransitions as Boolean));
                super.commitProperties();
              }
            

            Make sure you call setCurrentState() *before* you call super.commitProperties().  If you do it the other way around, then other state-dependent properties in your renderer (like state-dependent mxml attributes) will reflect the old state instead of the new state.  This is not as inefficient as it looks, since setCurrentState is basically a no-op when the current state is already equal to the requested new state.

             

            Now, just call invalidateProperties() whenever you change anything that might affect your renderer's state.  For example:

              // a custom property setter, "revealed"
              // when revealed is false, the renderer will stay in the "notLoaded" state
              // [see getCurrentRendererState(), below]
              //
              public function set revealed(value:Boolean):void {
                _revealed = value;
                invalidateProperties();
              }
            
              // the built-in property setter, "data"
              // set by the renderer owner (the list component) when the data item is bound
              // to the renderer instance. Our state depends on the contents of data, so we override
              // here, and call invalidateProperties(), which ultimately causes the framework to call
              // commitProperties(), which in turn will cause the renderer state to be set via a call
              // to our state logic in getCurrentRendererState().
              //
            
              override public function set data(value:Object):void {
                super.data = value;
                invalidateProperties();
              }
            
              // override built-in state logic to include logic for our own custom state, "notLoaded".
              //
              override protected function getCurrentRendererState():String {
                if( (!_revealed) || (data==null) ) {
                  return "notLoaded";
                }
            
                return super.getCurrentRendererState();
              }
            

            good luck!

            -Lee

            1 person found this helpful
            • 3. Re: Forcing State to Refresh in an ItemRenderer during a Drag and Drop
              vmvmvmvmvm Level 1

              Thanks Lee. I'll have to give that a try. I had basically given up and moved on to other projects, but I hope to revisit and see if your comments can get this working as I had hoped