Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 3.0 (http://www.flasher.ru/forum/forumdisplay.php?f=83)
-   -   Проблема с обновлением данных в собственном DataGrid, после удаления строки (http://www.flasher.ru/forum/showthread.php?t=138871)

Xero201 17.04.2010 20:20

Проблема с обновлением данных в собственном DataGrid, после удаления строки
 
Вложений: 4
Хочется сделать такой DataGrid, в котором можно добавлять произвольное количество строк. Для этого решил сделать его похожим на DataGridView из C# (рис. DataGridView)
Т.е. когда при переходе на последнюю строчку добавляется еще одна. А еще хочется нумерацию строк.
Для этого завел дополнительный столбец «№», со специальным DataGridCellEditor (рис. VDataGrid_begin)
В котором помимо визуальных настроек, добавлен слушатель KeyboardEvent.KEY_DOWN, для того, чтобы если нажата «DELETE» - удалить текущую строку.
Вот тут и возникла беда(.
При удалении любой строки, кроме предпоследней (т.е. той, что идет перед звездочкой) – все нормально. Но вот если удалить предпоследнюю, то строка со звездочкой столбец «№», меняет свою «*» на число. там где сейчас «3» раньше была звездочка((
Причем это происходит не сразу после удаления, а только при последующей активации DataGrid (звездочка внаглую заменяется номером строки). На рис. VDataGrid_begin, вместо «3» после удаления была «*».
Первая мысль была – ошибка где-то в циклах, которые захватывают при перенумерации и последнюю строку. Но тогда почему замена происходит не сразу, а только при повторном нажатии на DataGrid.
Вторая мысль – во всем виноват слушатель, который я запихнул в DataGridCellEditor, но что с ним можно сделать не знаю.
Помогите, пожалуйста.
Вот код VDataGrid (пример прилагается в архиве):
Код AS3:

package 
{
        import fl.controls.DataGrid;
        import fl.controls.dataGridClasses.DataGridCellEditor;
        import flash.display.Sprite;
        import fl.data.DataProvider;
        import flash.events.Event;
        import flash.events.KeyboardEvent;
        import flash.events.MouseEvent;
        import flash.text.*;
        import flash.ui.Keyboard;
 
        public class  VDataGrid extends Sprite
        {
                public var dg:DataGrid;
                var aColumns:Array;
                var aData:Array;
 
                public function VDataGrid(aColumns:Array) {
 
                        this.aColumns = aColumns;
                        aData=[];
 
                        begSet()
                }
 
                public function begSet():void {
 
                        aColumns.unshift("№");
                        dg.columns = aColumns;       
                        dg.editable = true;       
                        dg.columns[0].itemEditor = falseEditor();
 
                        dg.addEventListener(Event.CHANGE, testRow);               
 
                        for (var i = 0; i < aData.length; i++) {
                                aData[i]["№"] = i + 1;
                        }                       
                        aData.push(addS());//добавить пустую строку со звездочкой
                        dg.dataProvider = new DataProvider(aData);//обновить данные
 
                }
 
                private function falseEditor():DataGridCellEditor {
 
                          var tablEditor:DataGridCellEditor = new DataGridCellEditor();
 
                          tablEditor.textField.background = true;
                          tablEditor.textField.backgroundColor = 0xCCCCCC;
 
                          tablEditor.addEventListener(KeyboardEvent.KEY_DOWN, testKey);                 
 
                          var txt:TextField = tablEditor.textField;                         
                          txt.type = TextFieldType.DYNAMIC;
                          txt.selectable = false;
                          return tablEditor;
                }
 
 
                private function testKey(e:KeyboardEvent):void {
 
                        if (e.keyCode == Keyboard.DELETE) {                               
                                var index:uint = dg.selectedIndex;
                                aData.splice(index, 1);//удалить массив содержащий соответсвующую строку                       
                                for (var i = index; i < aData.length-1; i++) {//изменить номера все строчек, идущих после удаленной (кроме самой последней со звездочкой)
                                        aData[i]["№"] = i + 1;                                                                       
                                }
                                dg.dataProvider = new DataProvider(aData);       
 
                        }
                }
 
                private function viewData(e:Event = null):void {//посмотреть, какие данные хранятся в массиве для dataProvider
                        trace("viewData");
                        for each(var d in aData) {                                       
                                        trace(d["№"]+"  "+d["col1"]+"  "+d["col2"]);
                                }       
                }       
 
                private function addS():Array {//добавить строку со звездочкой
                        var row:Array = new Array();
                        for each(var col in aColumns) row[col] = "";// aData.length;
                        row["№"] = "*";
                        return row;
                }
 
                private function testRow(e:Event):void {//проверка, для добавления новой строки
                        if (dg.selectedItem["№"] == "*") {        //если выбрана строка со здездочкой добавить новую
                                aData[aData.length - 1]["№"] = aData.length;
                                aData.push(addS());                               
                                dg.dataProvider = new DataProvider(aData);
                        }
                }
 
        }
 
}


Xero201 21.04.2010 21:58

Стала ясна одна штука, я ошибался, когда думал, что не работает только удаление предпоследней строки)
Удаление любой строки происходит криво. Точнее как, функция testKey работает нормально. Ловит нажатия Delete, удаляет нужный элемент массива, заносится в dg.dataProvider. И при дебаге все на своих местах.
Но затем, после любой активации dg, происходит "восстание из мертвых": срока, которая была удалена, появляется и заменяет строку, следующую за ней. Причем и в dataProvider и в aData одновременно.
:eek:
Добавленно:

Не знаю почему это работает, но придумал следующий фокус:
Код AS3:

private function testKey(e:KeyboardEvent):void {
 
                        if (e.keyCode == Keyboard.DELETE) {                                                                       
                                dg.dispatchEvent(new MouseEvent(MouseEvent.MOUSE_DOWN)); //!!! отвлекающий маневр
                                dg.dispatchEvent(new MouseEvent(MouseEvent.MOUSE_UP));//типо ничего и не было)
                                var index:uint = dg.selectedIndex;
                                aData.splice(index, 1);
                                for (var i = index; i < aData.length-1; i++) {
                                        aData[i]["№"] = i + 1;                                                                       
                                }
                                dg.dataProvider = new DataProvider(aData);       
                        }
                }

Уф, неужели получилось)


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

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