Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • Home
  • SEARCH
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8102875
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 5, 20262026-06-05T23:21:35+00:00 2026-06-05T23:21:35+00:00

I am moving away from MXML and have built a custom component control within

  • 0

I am moving away from MXML and have built a custom component control within ActionScript.

I have the control displaying correctly. The problem comes after I remove it from the display list and add it back in again with the .addElement(control) method.

Here is the code that adds it back in again.

private function displayParameters(parameters:ArrayCollection):void{

   for(var index:int = 0; index<parameters.length; index++){

      if(parameters[index] is ReportControl){

          var control:ReportControl = parameters[index] as ReportControl;
          control.percentWidth = 100;
          vgParameters.addElement(control);
      }
   }
}

ReportControl is the base class for comboBoxMultiSelect which is shown below. There is nothing graphically special about ReportControl, it only serves as a programmatic interface for its concrete implementations (polymorphic).

public class comboBoxMultiSelect extends ReportControl{

    [Embed("../Assets/Icons/plus-16.png")]
    private var plusIcon:Class;
    [Embed("../Assets/Icons/minus-16.png")]
    private var minusIcon:Class;

    private var expanded:Boolean = false;
    private var buttonIconChanged:Boolean = false;

    private var _drp:ComboBox;
    private var _btnMultiple:Button;
    private var _horizontalGroup:HGroup;
    private var _multiSelector:ReportGridSelector;

    private var _multiSelection:Boolean = true;
    private var bMultiSelectionChanged:Boolean = false;        

    public function ToggleExpanded():void{
        expanded = !_expanded;
        buttonIconChanged = true;

        invalidateSize();
        invalidateProperties();
        invalidateDisplayList();
    }

    public function comboBoxMultiSelect(){
        super();
    }

    override protected function createChildren():void{

        super.createChildren();            

        if(!_horizontalGroup){
            _horizontalGroup = new HGroup();
            _horizontalGroup.gap = 0;
            _horizontalGroup.percentWidth = 100;
            _horizontalGroup.height = ReportControl.SIZE_DEFAULT_HEIGHT;
             addChild(_horizontalGroup);
        }

        if(!_drp){
            _drp = new ComboBox();
            _drp.text = GuiText;
            _drp.percentWidth = 100;
            _drp.height = ReportControl.SIZE_DEFAULT_HEIGHT; 
            _horizontalGroup.addElement(_drp);
        }

        if(!_btnMultiple && _multiSelection){
            _btnMultiple = new Button;
            _btnMultiple.setStyle("icon", plusIcon);
            _btnMultiple.width = 20;
            _btnMultiple.height = ReportControl.SIZE_DEFAULT_HEIGHT;
            _btnMultiple.visible = true;
            _btnMultiple.addEventListener(MouseEvent.CLICK,
                         function(event:MouseEvent):void{
                                 ToggleExpanded();   
                         });
            _horizontalGroup.addElement(_btnMultiple);
        }
    }

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

        if(buttonIconChanged){

            if(_expanded==true){
                _btnMultiple.setStyle("icon", minusIcon);
            }
            else{
                _btnMultiple.setStyle("icon", plusIcon);
            }
            buttonIconChanged = false;
        }

    }

    override protected function updateDisplayList(unscaledWidth:Number,
                                         unscaledHeight:Number):void{

        super.updateDisplayList(unscaledWidth, unscaledHeight);

        _horizontalGroup.width = unscaledWidth;
        _horizontalGroup.height = unscaledHeight;
    }

    override protected function measure():void{

        super.measure();
        measuredMinWidth = measuredWidth = ReportControl.SIZE_DEFAULT_WIDTH;

        //minimum size      //default size
        if(_expanded==true)
            measuredMinHeight= measuredHeight = 200;            
        else
            measuredMinHeight= measuredHeight = 
                               ReportControl.SIZE_DEFAULT_HEIGHT;
    }
}

When I add the control back in using vgParameters.addElement(control), the comboBoxMultiSelect is not rendering properly. The plusIcon inside the button _btnMultiple is not postioned correctly at first, but then quickly corrects itself about 0.5-1 secs later.

I pretty sure the problem lies within comboBoxMultiSelect, just not sure how to force the icon to stay in the same place.

This is highly annoying after all my hard work, anyone have ideas as to what I am doing wrong?

Thanks 🙂

UPDATE —–> Here is the ReportControl code

[Event (name= "controlChanged", type="Reporting.ReportControls.ReportControlEvent")]
[Event (name= "controlIsNowValid", type="Reporting.ReportControls.ReportControlEvent")]
public class ReportControl extends UIComponent
{
    private var _guiText:String;
    private var _amfPHPArgumentName:String;
    private var _reportResult:ReportResult;
    private var _sequence:int;
    private var _reportId:int;
    private var _controlConfiguration:ReportParameterVO;
    private var _isValid:Boolean = false;
    internal var _selection:Object;

    /**
     * SIZE_DEFAULT_HEIGHT = 22
     */
    internal static const SIZE_DEFAULT_HEIGHT:int = 22;

    /**
     * SIZE_DEFAULT_WIDTH = 150
     */
    internal static const SIZE_DEFAULT_WIDTH:int = 150;

    public function get ControlConfiguration():ReportParameterVO{
        return _controlConfiguration;
    }

    public function set ControlConfiguration(value:ReportParameterVO):void{

        _controlConfiguration = value;            
        _guiText = (value ? value.GuiText:"");
        _amfPHPArgumentName = (value ? value.AMFPHP_ArgumentName: "");
        _sequence = (value ? value.Sequence : null);
        _reportId = (value ? value.ReportId : null);            
    }

    public function get IsValid():Boolean{
        return _isValid;
    }

    public function get ReportID():int{
        return _reportId;
    }

    public function get Sequence():int{
        return _sequence;
    }

    public function get ControlRepResult():ReportResult{
        return _reportResult;
    }
    public function set ControlRepResult(value:ReportResult):void{
        _reportResult = value;
    }

    internal function set Selection(value:Object):void{
        _selection = value;
    }

    internal function get Selection():Object{
        return _selection;
    }

    public function get ParameterSelection():Object{
        return _selection;
    }

    public function get GuiText():String{
        return _guiText;
    }

    public function get AmfPHPArgumentName():String{
        return _amfPHPArgumentName;
    }

    public function ReportControl(){
        //TODO: implement function
        super();
    }

    public function dispatchControlChanged():void{
        this.dispatchEvent(new ReportControlEvent(ReportControlEvent.CONTROL_CHANGED, this, true));
    }
    public function dispatchControlIsNowValid():void{
        this.dispatchEvent(new ReportControlEvent(ReportControlEvent.CONTROL_IS_NOW_VALID, this, true));
    }

    public function addSelfToValueObject(valueObject:Object):Object{
        valueObject[AmfPHPArgumentName] = _selection;
        return valueObject;
    }

}
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-05T23:21:37+00:00Added an answer on June 5, 2026 at 11:21 pm

    I’ll try to give you an example of what I mean with the Spark skinning architecture we’ve discussed in the comments above. It’s not directly an answer to your question, but I thought you might find it interesting. I will have to make it somewhat simpler than your component for brevity’s sake and because you seem to have stripped out some of the code for your question so I can’t know exactly what it’s supposed to do.

    This will be a component that will let you toggle between a normal and an expanded state through the click of a Button. First we’ll create the skin class. Normally you’d create the host component first, but it’ll be easier to explain this way.

    <!-- my.skins.ComboBoxMultiSelectSkin -->
    <s:Skin xmlns:fx="http://ns.adobe.com/mxml/2009" 
            xmlns:s="library://ns.adobe.com/flex/spark"
            height.normal="25" height.expanded="200">
    
        <fx:Metadata>
            [HostComponent("my.components.ComboBoxMultiSelect")]
        </fx:Metadata>
    
        <s:states>
            <s:State name="normal" />
            <s:State name="expanded" />
        </s:states>
    
        <s:layout>
            <s:HorizontalLayout gap="0" />
        </s:layout>
    
        <s:ComboBox id="comboBox" width="100%" />
        <s:Button id="toggleButton" width="20"
                  icon.normal="@Embed('../Assets/Icons/plus-16.png')"
                  icon.expanded="@Embed('../Assets/Icons/minus-16.png')"/>
    
    </s:Skin>
    

    Thus we’ve set up completely how your component will look and how it will lay out. Do you feel your headaches dissipating? I for one find this quite elegant. We have the two states and the height of the component will adjust to the currently selected state as will the icon of the Button. How and when the state is toggled is component behaviour and will be defined in the host component.

    Now let’s create that host component in plain ActionScript. For this we’ll extend SkinnableComponent (note that it could also extend your ReportControl if that would extend SkinnableComponent instead of UIComponent).

    [SkinState("normal")]
    [SkinState("expanded")]
    public class ComboBoxMultiSelect extends SkinnableComponent {
    
        [SkinPart(required="true")]
        public var toggleButton:IEventDispatcher;
    
        [SkinPart(required="true")]
        public var comboBox:ComboBox;
    
        private var expanded:Boolean;
    
        override protected function partAdded(partName:String, instance:Object):void {
            super.partAdded(partName, instance);
    
            switch (instance) {
                case toggleButton:  
                    toggleButton.addEventListener(MouseEvent.CLICK, handleToggleButtonClick); 
                    break;
                case comboBox:
                    comboBox.addEventListener(IndexChangeEvent.CHANGE, handleComboSelection);
                    break;
            }
        }
    
        private function handleToggleButtonClick(event:MouseEvent):void {
            toggleExpanded();
        }
    
        private function handleComboSelection(event:IndexChangeEvent):void {
            //handle comboBox selection
        }
    
        protected function toggleExpanded():void {
            expanded = !expanded;
            invalidateSkinState();
        }
    
        override protected function getCurrentSkinState():String {
            return expanded ? "expanded" : "normal";
        }
    }
    

    Allright, there’s a lot more going on here.

    • First look at the SkinState metadata declarations: when a skin class is assigned to the component, the compiler will check whether that skin has the required states implemented.
    • Then the SkinPart declarations: the name of the property on the host component must exactly match the id of the tag in the skin class. As required is set to true the compiler will check whether these components do really exist in the skin. If you want optional skin parts, you set it to false.
    • Note that the type of toggleButton is IEventDispatcher: from the host component’s point of view, all toggleButton has to do, is dispatching CLICK events. This means that we could now create a skin with <s:Image id="toggleButton" source="..." /> and the whole thing would keep working the same way. See how powerful this is?
    • Because the skinpart properties are not assigned immediately, we override the partAdded() method which will be executed whenever a component becomes available. In most cases this is the place where you hook up your event listeners.
    • In the toggleExpanded() method, we toggle the boolean just like the component in your question, however we only invalidate the skin state. This will cause the skin to call the getCurrentSkinState() method and update its state to whatever value is returned.

    Et voilà! You have a working component with the behaviour nicely separated into an actionscript class and you didn’t have to worry about the layout intricacies. And if you ever wish to create a component with the same behaviour, but it should expand horizontally instead of vertically: just create a new skin that adjusts the width instead of the height and assign that to the same host component.

    Oh wait! I nearly forgot to tell you how to assign the skin to the components. You can do it either inline:

    <c:ComboBoxMultiSelect skinClass="my.skins.ComboBoxMultiSelectSkin" />
    

    or through styling:

    @namespace c "my.components.*";
    
    c|ComboBoxMultiSelect {
        skinClass: ClassReference("my.skins.ComboBoxMultiSelectSkin")
    }
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I have just started using TFS2010 as a source control, moving away from VSS.
We're moving away from TFS as a source control/build service. We're now using TeamCity,
I'm totally new to Flex (moving away from Java for now :(). I have
I have posted a question before, Moving away from VSS , in which I
I'm moving away from Serializable objects (need to cache and move things around -
I'm rewriting everything and moving away from absolute positions and instead using floats to
From my research so far, Linux is moving away from allowing access to physical
PREFACE: Yes we're moving away from VSS in the next few months. One of
I'm investigating moving away from an Oracle connection pool and using the Tomcat connection
We're thinking of moving away from Sharepoint 2003 and to HP Quality Center for

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.