apache-flexflex4halo

How do I update an mxml property dynamically in Flex?


I'm using Flex 4.0, with the Halo theme, and a custom component that I have the source of. I want to call the component with a parameter to hide or show some items. The parameter is dynamic, meaning it is set in a method after the mxml has loaded.

Snippet:

<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
    layout="absolute"
    xmlns:ns1="de.aggro.components.*"
    width="100%"
    height="100%"
    initialize="init();"
>

<mx:Script>
    <![CDATA[
        [Bindable]
        public var allowwindowmanipulation:Boolean = true;

        internal function init():void {
            allowwindowmanipulation = false;
        }
    ]]>
</mx:Script>
<mx:states>
    <mx:State name="st">
        ...
        <ns1:CollapsableTitleWindow width="956" height="395" x="294" y="484" id="wnd" title="title" allowClose="{allowwindowmanipulation}">
    </mx:State>
</mx:states>

</mx:Application>

CollapsableTitleWindow code (snippet):

public class CollapsableTitleWindow extends Panel implements ICTWindow {    
    public var allowClose:Boolean = true;

    function CollapsableTitleWindow(){
        super();
        addEventListener(FlexEvent.CREATION_COMPLETE, initializeHandler);
    }

    protected override function createChildren():void{
        super.createChildren();         

        //Create the Buttons
        closeButton = new Sprite();

        if(allowClose==true){
            titleBar.addChild(closeButton);
            drawCloseButton(true);
        }
    }
}

Now, when I run this code, the value given to the constructor of CollapsableTitleWindow is true for the allowClose variable. So when createChildren() is called, the button is drawn.

How can I change the behaviour? I don't mind if the button first gets drawn then later gets removed, if need be, but I don't know how I do this binding of parameter values.

When I for instance change the title property to {allowClose}, the boolean value of false gets shown, even though probably a true is passed at first.


Solution

  • Note: edited to reflect feedback

    Since you're using Flex 4, you should probably do this with a skin and States within the skin. But if you want to do it through code, try something like this:

    protected var _allowClose:Boolean=true;
    protected var _allowCloseChanged::Boolean=true;
    protected var _closeButton:Sprite = new Sprite();
    
    
    public function get allowClose():Boolean {
        return _allowClose;
    }
    
    public function set allowClose(value:Boolean):void {
        if (value != _allowClose) {
           _allowClose=value;
           _allowCloseChanged=true;
           invalidateProperties();
        }
    }
    
    override protected function commitProperties():void {
       if (_allowCloseChanged) {
           if (_allowClosed) {
                titlebar.addChild(_closeButton);
                drawCloseButton(true);
           } else {
                titleBar.removeChild(_closeButton);
           }
           //you need to set this back false...sorry I left that out
           _allowCloseChanged=false;
       }
       super.commitProperties();
    }
    

    Note: in this case, you no longer need to override createChildren