Динамическое добавление переключателя дважды - Ошибка № 2025: предоставленный объект DisplayObject должен быть дочерним по отношению к вызывающей стороне - PullRequest
1 голос
/ 02 ноября 2010

У меня есть приложение FLEX 4, и у меня возникают проблемы с динамическим добавлением элементов управления пользовательского интерфейса. В основном с переключателями.

Вот пример, который демонстрирует мою проблему:

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

^ Запустите это. Нажмите кнопку «Добавить панель». Затем нажмите «Очистить». Затем снова нажмите кнопку «Добавить панель». Вы увидите ошибку:

ArgumentError: Ошибка № 2025: поставляемый DisplayObject должен быть дочерним звонящего. на flash.display :: DisplayObjectContainer / getChildIndex () в mx.core :: Container / getChildIndex () [E: \ dev \ 4.0.0 \ frameworks \ projects \ framework \ src \ mx \ core \ Container.as: 2833] в mx.containers :: Panel / getChildIndex () [E: \ dev \ 4.0.0 \ frameworks \ projects \ framework \ src \ mx \ container \ Panel.as: 1174] в mx.controls :: RadioButtonGroup / breadthOrderCompare () [E: \ dev \ 4.0.0 \ frameworks \ projects \ framework \ src \ mx \ controls \ RadioButtonGroup.as: 600] в mx.controls :: RadioButtonGroup / breadthOrderCompare () [E: \ dev \ 4.0.0 \ frameworks \ projects \ framework \ src \ mx \ controls \ RadioButtonGroup.as: 611] в mx.controls :: RadioButtonGroup / breadthOrderCompare () [E: \ dev \ 4.0.0 \ frameworks \ projects \ framework \ src \ mx \ controls \ RadioButtonGroup.as: 611] в массиве $ / _ sort () в массиве / http://adobe.com/AS3/2006/builtin::sort() на 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] в mx.controls :: RadioButton / addToGroup () [E: \ dev \ 4.0.0 \ frameworks \ projects \ framework \ src \ mx \ controls \ RadioButton.as: 574] в mx.controls :: RadioButton / commitProperties () [E: \ dev \ 4.0.0 \ frameworks \ projects \ framework \ src \ mx \ controls \ RadioButton.as: 514] в mx.core :: UIComponent / validateProperties () [E: \ dev \ 4.0.0 \ frameworks \ projects \ framework \ src \ mx \ core \ UIComponent.as: 7772] в mx.managers :: LayoutManager / validateProperties () [E: \ dev \ 4.0.0 \ frameworks \ projects \ framework \ src \ mx \ Manager \ LayoutManager.as: 572] в mx.managers :: LayoutManager / doPhasedInstantiation () [E: \ dev \ 4.0.0 \ frameworks \ projects \ framework \ src \ mx \ Manager \ LayoutManager.as: 730] в mx.managers :: LayoutManager / doPhasedInstantiationCallback () [E: \ dev \ 4.0.0 \ frameworks \ projects \ framework \ src \ mx \ Manager \ LayoutManager.as: 1072]

Я не понимаю, почему я не могу повторно добавить переключатель после первого перехода на него? Это происходит только тогда, когда у меня есть радио кнопки, добавляемые к форме / панели.

Если вы закомментируете код для переключателя (секция комментариев № 3), вы можете легко добавить панели заново. Попробуйте, закомментируйте это, и вы можете добавить, повторно добавить панель без проблем:

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

Почему это происходит и как я могу это исправить? Почему это происходит только с переключателями? Я могу использовать чекбоксы, текстовые входы, что угодно, и это не вызывает исключений вроде этого ... какие-нибудь идеи?

1 Ответ

2 голосов
/ 02 ноября 2010

Вы не добавляете свои радиокнопки в группу радиокнопок. Начните делать это, и вы должны перестать видеть ошибки.

Тем не менее, эта строка для меня загадка:

myList.addChild(thePanel);

Почему вы добавляете детей в элемент управления списком? Вы не должны использовать список в качестве контейнера. Следует сосредоточиться только на отображении элементов в вашем DataProvider. Класс списка не имеет возможности для размещения или размещения элементов, не входящих в dataProvider.

Кроме того, при создании нового RadioButton у вас нет скобок:

var myRadioButton:RadioButton = new RadioButton;

Теоретически это не должно иметь никакого значения, но я всегда предпочитаю держать скобки.

Вот рабочий код:

<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>
...