Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   Flex (http://www.flasher.ru/forum/forumdisplay.php?f=84)
-   -   ComboBox-ы в DataGrid-е (http://www.flasher.ru/forum/showthread.php?t=117800)

neru80 06.11.2008 20:15

ComboBox-ы в DataGrid-е
 
Здравствуйте!

Преамбула
Ни в доках, ни ан форумах, ни в кукбуке не нашёл готового решения и решил написать собственный рендерер для ComboBox-а в DataGrid-е.
Необходимо: есть некая таблица, одно из полей содержит id значения из другой таблицы (справочника). Нужно выводить в DataGrid-е вместо поля с id ComboBox-ы с названиями элементов справочника.

Реализация
Flex Builder 3

Тестовое приложение
Код:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" initialize="onInit()">
        <mx:Script>
                <![CDATA[
                        import flash.events.*;
                        import mx.collections.ArrayCollection;
                        import mx.events.*;
                        import mx.controls.*;
                       
                        import datech.controls.DropInGridComboBox;
                       
                        [Bindable]
                        private var factory:ClassFactory;
                       
                        protected function onInit():void{
                                factory = new ClassFactory(DropInGridComboBox);
                                factory.properties = {values:cards, showField:"label", keyField:"Registrator"};
                        }

                        [Bindable]
            public var cards:ArrayCollection = new ArrayCollection(
                [ {label:"Ilya", Registrator:"{26BE86EB-0A5F-4454-82DF-529B9317BC0A}"},
                  {label:"Alex", Registrator:"{3769C53C-E392-4341-9DA3-B4D16DB18CD9}"}]);
           
            [Bindable]
            public var papap:ArrayCollection = new ArrayCollection(
                [ {KeyWords:"keyword1", Registrator:"{26BE86EB-0A5F-4454-82DF-529B9317BC0A}"},
                  {KeyWords:"keyword2", Registrator:"{26BE86EB-0A5F-4454-82DF-529B9317BC0A}"},
                  {KeyWords:"keyword3", Registrator:"{26BE86EB-0A5F-4454-82DF-529B9317BC0A}"},
                  {KeyWords:"keyword4", Registrator:"{26BE86EB-0A5F-4454-82DF-529B9317BC0A}"},
                  {KeyWords:"keyword5", Registrator:"{26BE86EB-0A5F-4454-82DF-529B9317BC0A}"},
                  {KeyWords:"keyword6", Registrator:"{26BE86EB-0A5F-4454-82DF-529B9317BC0A}"},
                  {KeyWords:"keyword7", Registrator:"{26BE86EB-0A5F-4454-82DF-529B9317BC0A}"},
                  {KeyWords:"keyword8", Registrator:"{26BE86EB-0A5F-4454-82DF-529B9317BC0A}"},
                  {KeyWords:"keyword9", Registrator:"{26BE86EB-0A5F-4454-82DF-529B9317BC0A}"},
                  {KeyWords:"keyword10", Registrator:"{26BE86EB-0A5F-4454-82DF-529B9317BC0A}"},
                  {KeyWords:"keyword11", Registrator:"{26BE86EB-0A5F-4454-82DF-529B9317BC0A}"},
                  {KeyWords:"keyword12", Registrator:"{26BE86EB-0A5F-4454-82DF-529B9317BC0A}"},
                  {KeyWords:"keyword13", Registrator:"{26BE86EB-0A5F-4454-82DF-529B9317BC0A}"}]);
                ]]>
        </mx:Script>

        <mx:DataGrid y="111" id="adg1" width="583" x="176" dataProvider="{papap}"
                borderStyle="solid" borderColor="#410970" editable="true">
                <mx:columns>
                        <mx:DataGridColumn headerText="Key Words" dataField="KeyWords" />
                        <mx:DataGridColumn headerText="RRR" itemRenderer="{factory}" editable="false" />
                </mx:columns>
        </mx:DataGrid>
       
</mx:Application>

Компонент:
Код:

package datech.controls
{
        import mx.collections.ArrayCollection;
        import mx.controls.ComboBox;
        import mx.controls.DataGrid;
        import mx.controls.dataGridClasses.DataGridListData;
        import mx.controls.listClasses.IListItemRenderer;
        import mx.core.IFactory;
        import mx.events.FlexEvent;

        public class DropInGridComboBox extends ComboBox implements IFactory
        {
               
                /////// PRIVATE FIELDS ///////
                [Bindable]
                private var _values:ArrayCollection;
                private var _showfield:String;
                private var _keyfield:String;
                //////////////////////////////
               
               
               
                /////// PROPERTIES FOR ClassFactory CLASS ///////
                public function set values(value:ArrayCollection):void{
                        _values = value;
                        invalidateNestedComboBox();
                }
                public function set showField(value:String):void{
                        super.labelField = value;
                        _showfield = value;
                        invalidateNestedComboBox();
                }
                public function set keyField(value:String):void{
                        _keyfield = value;
                        invalidateDisplayList();
                }
                /////////////////////////////////////////////////
               
               
               
                /////// ComboBox UTILITIES ///////
                protected function invalidateNestedComboBox():void{
                        if(_values == null || _showfield == null || _showfield == "") return;

                        this.dataProvider = _values;
                        this.labelField = _showfield;
                       
                        invalidateDisplayList();
                }
                protected function setCurrentItem(cur:Object):void{
                        for(var i:int = 0; i<_values.length; i++)
                                if(_values[i][_keyfield] == cur[_keyfield])
                                {
                                        super.data = _values[i];
                                        this.selectedIndex = i;
                                        break;
                                }
                }
                //////////////////////////////////
               
               
               
                /////// CombobBox Data stuff overriding ///////
                override public function set data(value:Object):void{
                        setCurrentItem(value);
                        invalidateProperties();
                        dispatchEvent(new FlexEvent(FlexEvent.DATA_CHANGE));
                }
                override public function set selectedIndex(value:int):void{
                        if(super.selectedIndex != value && value >= 0)
                        {
                                super.selectedIndex = value;
                                if(listData is DataGridListData)
                                {
                                        var ld:DataGridListData = (this.listData as DataGridListData);
                                        var dg:DataGrid = ld.owner as DataGrid;
                                        dg.dataProvider[ld.rowIndex][this._keyfield] = _values[value][this._keyfield];
                                }
                        }
                }
                //////////////////////////////////////////////



                /////// IFactory IMPLEMENTATION ///////
                public function newInstance():*{
                        var ret:DropInGridComboBox = new DropInGridComboBox();
                        return ret;
                }
                //////////////////////////////////////
        }
}

ПРОБЛЕМА:
При изменении значений в комбобоксе одной из строк может меняться (закономерность не вывел) значение в комбобоксе другой строки.

Что характерно, пробовал отлаживаться, и увидел, что в классе DropInGridComboBox в метод newInstance() мы никогда не заходим, а в конструктор попадаем только 9 раз вместо 13 (общее количество строк в гриде).

Добавлено через 17 минут
UPD: воспроизводится, если есть скроллы в гриде

sabbats 07.11.2008 07:38

Тебе могут помочь те, кто решал данную проблему.Посмотри

neru80 07.11.2008 19:52

Цитата:

Сообщение от sabbats (Сообщение 775243)
Тебе могут помочь те, кто решал данную проблему.Посмотри

не, это я уже читал - не мой случай. помогло вот это тынц

исправленный код компонента (если, конечно, кому интересно :-) )

Код:

package datech.controls
{
        import mx.collections.ArrayCollection;
        import mx.controls.ComboBox;
        import mx.controls.dataGridClasses.DataGridListData;
        import mx.events.FlexEvent;
        import mx.events.ListEvent;

        public class DropInGridComboBox extends ComboBox{
                public function DropInGridComboBox(){
                        super();
                        this.addEventListener(ListEvent.CHANGE, onSelectionChange);
                }
               
                /////// PRIVATE FIELDS ///////
                [Bindable]
                private var _values:ArrayCollection;
                private var _showfield:String;
                private var _keyfield:String;
                //////////////////////////////
               
               
               
                /////// PROPERTIES FOR ClassFactory CLASS ///////
                public function set values(value:ArrayCollection):void{
                        _values = value;
                        invalidateNestedComboBox();
                }
                public function set showField(value:String):void{
                        super.labelField = value;
                        _showfield = value;
                        invalidateNestedComboBox();
                }
                public function set keyField(value:String):void{
                        _keyfield = value;
                        invalidateDisplayList();
                }
                /////////////////////////////////////////////////
               
               
               
                /////// ComboBox UTILITIES ///////
                protected function invalidateNestedComboBox():void{
                        if(_values == null || _showfield == null || _showfield == "") return;

                        this.dataProvider = _values;
                        this.labelField = _showfield;
                       
                        invalidateDisplayList();
                }
                protected function setCurrentItem(cur:Object):void{
                        for(var i:int = 0; i<_values.length; i++)
                                if(_values[i][_keyfield] == cur[_keyfield])
                                {
                                        super.data = cur;
                                        this.selectedIndex = i;
                                        break;
                                }
                }
                //////////////////////////////////
               
               
               
                /////// CombobBox Data stuff overriding ///////
                override public function set data(value:Object):void{
                        setCurrentItem(value);
                        invalidateProperties();
                        dispatchEvent(new FlexEvent(FlexEvent.DATA_CHANGE));
                }
                private function onSelectionChange(evt:ListEvent):void{
                        if(this.listData is DataGridListData)
                                {
                                        var ownerList:DataGridListData = DataGridListData(this.listData);
                                        this.data[ownerList.dataField] = this.selectedItem[this._keyfield];
                                }       
                }
                //////////////////////////////////////////////
               
               
                /////// OTHER UTILITIES ///////
            static public function compareFunctionAsString(fieldName:String, obj1:Object, obj2:Object):int
            {
                    var str1:String = obj1[fieldName].toString();
                    var str2:String = obj2[fieldName].toString();
                    var ret:int;
                    if(str1 < str2)
                            ret = -1;
                    else if (str1 > str2)
                            ret = 1;
                    else
                            ret = 0;
                      return ret;
            }
                ///////////////////////////////
        }
}


Захаров 12.11.2008 14:59

Вы не могли бы рассказать что привело к адекватной отрисовке?
У меня возникает проблемма с установкой чекбокса в случайном порядке при скролинге дерева!

neru80 12.11.2008 19:00

Цитата:

Сообщение от Захаров (Сообщение 776450)
Вы не могли бы рассказать что привело к адекватной отрисовке?
У меня возникает проблемма с установкой чекбокса в случайном порядке при скролинге дерева!

C чекбоксами у меня была такая же проблема (в датагриде) при editable="false" у колонки. Пролечилось с параметрами editable="true" rendererIsEditor="true" editorDataField="selected".


Часовой пояс GMT +4, время: 08:03.

Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.