开发者

Adding Radio Button dynamically, twice - Error #2025: The supplied DisplayObject must be a child of the caller

开发者 https://www.devze.com 2023-01-22 22:50 出处:网络
I have a FLEX 4 application and I am having some trouble adding UI controls dynamically. Mostly with radio buttons.

I have a FLEX 4 application and I am having some trouble adding UI controls dynamically. Mostly with radio buttons.

Here is an example that demonstrates my problem:

<s:Application
    xmlns:fx="http://ns.adobe.com/mxml/2009"
    xmlns:s="library://ns.adobe.com/flex/spark" 
    xmlns:mx="library://ns.adobe.com/flex/mx"
    creationPolicy="all"
    >

    <fx:Script>
        <![CDATA[ 
            import mx.containers.Form;
            import mx.containers.Panel;
            import mx.controls.Label;
            import mx.controls.NumericStepper;
            import mx.controls.RadioButton;


            private var theChar:String = "B";

            protected function btnAdd_clickHandler(event:MouseEvent):void
            {                           

                var theForm:Form = new Form();               
                theForm.label = theChar;

                //1. Label
                var myLabel:Label = new Label();
                myLabel.text = "My Label";
                myLabel.width=120;
                theForm.addChild(myLabel);

                //2. Numeric Stepper
                var myNumStepper:NumericStepper = new NumericStepper();
                myNumStepper.id = "numPointHigh" + theChar;
                myNumStepper.name = "numPointHigh" + theChar;
                myNumStepper.minimum = 0;
                myNumStepper.maximum = 120;
                myNumStepper.width = 50;
                myNumStepper.height = 30;
                theForm.addChild(myNumStepper);

                //3. radio button
                var myRadioButton:RadioButton = new RadioButton;
                myRadioButton.id = "myRadioButton" + theChar;
                myRadioButton.name = "myRadioButton" + theChar;
                myRadioButton.label = "my radio button";
                myRadioButton.selected = true;
                theForm.addChild(myRadioButton);

                //4. Panel
                var thePanel:Panel = new Panel();
                thePanel.width = 300;
                thePanel.height = 475;
                thePanel.name=theChar;
                thePanel.title = "My Profile Panel";
                thePanel.setStyle("backgroundColor", "blue");

                //add the form to the panel
                thePanel.addChild(theForm);

                //add the Panel to the list control
                myContainer.addChild(thePanel);

            }

            protected function btnClear_clickHandler(event:MouseEvent):void
            {
                var numChildren:Number = myContainer.numChildren;
                for(var i:Number=numChildren - 1; i > -1; i--){
                    myContainer.removeChildAt(i);
                }
            }

        ]]>
    </fx:Script>

    <mx:VBox width="100%">
        <mx:Panel id="myContainer" />
        <mx:Button id="btnAdd" label="Add a panel" click="btnAdd_clickHandler(event)" color="black"/>
        <mx:Button id="btnClear" label="Clear" click="btnClear_clickHandler(event)" color="black" />
    </mx:VBox>

</s:Application>

^ Run that. Click the "Add a panel" button. Then click "Clear". Then click the "Add a panel" button again. You will see the error:

ArgumentError: Error #2025: The supplied DisplayObject must be a child of the caller. at flash.display::DisplayObjectContainer/getChildIndex() at mx.core::Container/getChildIndex()[E:\dev\4.0.0\frameworks\projects\framework\src\mx\core\Container.as:2833] at mx.containers::Panel/getChildIndex()[E:\dev\4.0.0\frameworks\projects\framework\src\mx\containers\Panel.as:1174] at mx.controls::RadioButtonGroup/breadthOrderCompare()[E:\dev\4.0.0\frameworks\projects\framework\src\mx\controls\RadioButtonGroup.as:600] at mx.controls::RadioButtonGroup/breadthOrderCompare()[E:\dev\4.0.0\frameworks\projects\framework\src\mx\controls\RadioButtonGroup.as:611] at mx.controls::RadioButtonGroup/breadthOrderCompare()[E:\dev\4.0.0\frameworks\projects\framework\src\mx\controls\RadioButtonGroup.as:611开发者_运维知识库] at Array$/_sort() at Array/http://adobe.com/AS3/2006/builtin::sort() at mx.controls::RadioButtonGroup/http://www.adobe.com/2006/flex/mx/internal::addInstance()[E:\dev\4.0.0\frameworks\projects\framework\src\mx\controls\RadioButtonGroup.as:465] at mx.controls::RadioButton/addToGroup()[E:\dev\4.0.0\frameworks\projects\framework\src\mx\controls\RadioButton.as:574] at mx.controls::RadioButton/commitProperties()[E:\dev\4.0.0\frameworks\projects\framework\src\mx\controls\RadioButton.as:514] at mx.core::UIComponent/validateProperties()[E:\dev\4.0.0\frameworks\projects\framework\src\mx\core\UIComponent.as:7772] at mx.managers::LayoutManager/validateProperties()[E:\dev\4.0.0\frameworks\projects\framework\src\mx\managers\LayoutManager.as:572] at mx.managers::LayoutManager/doPhasedInstantiation()[E:\dev\4.0.0\frameworks\projects\framework\src\mx\managers\LayoutManager.as:730] at mx.managers::LayoutManager/doPhasedInstantiationCallback()[E:\dev\4.0.0\frameworks\projects\framework\src\mx\managers\LayoutManager.as:1072]

I do not understand why I cannot re-add the radio button, after the first go at it? It is only happening when I have radio buttons being added to the form/panel.

If you comment out the code for the radio button (comment section #3.) you can re-add the panels easily. Try it, comment this out and you can add, re-add the panel with no problem:

            //3. radio button
            //var myRadioButton:RadioButton = new RadioButton;
            //myRadioButton.id = "myRadioButton" + theChar;
            //myRadioButton.name = "myRadioButton" + theChar;
            //myRadioButton.label = "my radio button";
            //myRadioButton.selected = true;
            //theForm.addChild(myRadioButton);

Why is this happening and how do I fix it? Why is this only happening to radio buttons? I can use checkboxes, textinputs, whatever and it doesn't throw exceptions like this...any ideas?


You aren't adding your radio buttons to a radio button group. Start doing that and you should stop seeing errors.

That said, this line is a mystery to me:

myList.addChild(thePanel);

Why are you adding children to a list control? You shouldn't be using a list as a container. It should only focus on displaying items in your DataProvider. A list class has no facility for positioning or laying out elements not in the dataProvider.

Additionally, you don't have parenthesis when creating the new RadioButton:

var myRadioButton:RadioButton = new RadioButton;

In theory that shouldn't make a difference, but it is always my preference to keep the parenthesis in.

Here is working code:

<s:Application
    xmlns:fx="http://ns.adobe.com/mxml/2009"
    xmlns:s="library://ns.adobe.com/flex/spark" 
    xmlns:mx="library://ns.adobe.com/flex/mx"
    creationPolicy="all"
    >

    <fx:Script>
        <![CDATA[ 
            import mx.containers.Form;
            import mx.containers.Panel;
            import mx.controls.Label;
            import mx.controls.NumericStepper;
            import mx.controls.RadioButton;
            import mx.controls.RadioButtonGroup;

            import spark.components.RadioButtonGroup;


            private var theChar:String = "B";

            protected function btnAdd_clickHandler(event:MouseEvent):void
            {                           

                var theForm:Form = new Form();               
                theForm.label = theChar;

                //1. Label
                var myLabel:Label = new Label();
                myLabel.text = "My Label";
                myLabel.width=120;
                theForm.addChild(myLabel);

                //2. Numeric Stepper
                var myNumStepper:NumericStepper = new NumericStepper();
                myNumStepper.id = "numPointHigh" + theChar;
                myNumStepper.name = "numPointHigh" + theChar;
                myNumStepper.minimum = 0;
                myNumStepper.maximum = 120;
                myNumStepper.width = 50;
                myNumStepper.height = 30;
                theForm.addChild(myNumStepper);

                //3. radio button
                var radioButtonGroup : mx.controls.RadioButtonGroup = new mx.controls.RadioButtonGroup();
                var myRadioButton:RadioButton = new RadioButton();
                myRadioButton.id = "myRadioButton" + theChar ;
                myRadioButton.name = "myRadioButton" + theChar ;
                myRadioButton.group = radioButtonGroup ;
                myRadioButton.label = "my radio button";
                myRadioButton.selected = true;
                theForm.addChild(myRadioButton);

                //4. Panel
                var thePanel:Panel = new Panel();
                thePanel.width = 300;
                thePanel.height = 475;
                thePanel.name=theChar;
                thePanel.title = "My Profile Panel";
                thePanel.setStyle("backgroundColor", "blue");

                //add the form to the panel
                thePanel.addChild(theForm);

                //add the Panel to the list control
                myList.addChild(thePanel);

            }

            protected function btnClear_clickHandler(event:MouseEvent):void
            {
                var numChildren:Number = myList.numChildren;
                for(var i:Number=numChildren - 1; i > -1; i--){
                    myList.removeChildAt(i);
                }
            }

        ]]>
    </fx:Script>

    <mx:VBox width="100%">
        <!--<mx:List id="myList" />-->
        <mx:VBox id="myList" />
        <mx:Button id="btnAdd" label="Add a panel" click="btnAdd_clickHandler(event)" color="black"/>
        <mx:Button id="btnClear" label="Clear" click="btnClear_clickHandler(event)" color="black" />
    </mx:VBox>

</s:Application>
0

精彩评论

暂无评论...
验证码 换一张
取 消