3 Replies Latest reply on Feb 8, 2011 2:24 PM by benschmidtke

    Wait for Renderers to Display

    bucpatr1 Level 2

      I'm testing a component with an editable DataGrid with custom item renderers. I wanted to use a sequence to simulate the user modifying a cell in the datagrid, but to be able to do that, I have to first make sure all the visible renders have been added and drawn. I've tried waiting for creationComplete and show but both of those events can potentially be dispatched before the renderers are added. Is there any event I can listen for in my test that will guarantee all the renderers have been drawn and displayed for the visible section of the datagrid?

        • 1. Re: Wait for Renderers to Display
          benschmidtke

           

          There is no global event to watch for when all visible renderers are available. The definition for such a event is quite subjective given all the various situations renderers are drawn combined with the item renderer recycling lifecycle (as I like to call it). Then there is also certain scrolling conditions based on the size of the grid combined with row height, the entire grid can drop and redraw all renderers at will. I doubt such a event would ever exist.

           

          Since you can only have one editor at a time, instead of worring about the entire grid, think of the problem as how can I get the item renderer for the data object I want to edit. If you know what you want to edit, then it becomes easier to accomplish.

           

          The way we accomplished this recently with AdvancedDataGrid in Flex 3 (it should be similar) is add a event listener for FlexEvent.UPDATE_COMPLETE to the datagrid. When that event fires, you are going to search for the renderer based on the data object you want to edit using dataGrid.itemToItemRenderer ( dataObject ). If it returns a itemRenderer then it is in the grid. Once you have the item renderer, you now can determine where you want to spawn the itemEditor.

           

          There have been times with Tree where the component can return a renderer before the item is actually in the display. This is because the Update_Complete event is not based on when the Item renderer is added to the screen but when the grid's display updates for whatever reason. This can present a race condition where the renderer has been assigned the data object, injected into the dictionary as a Item renderer in the display but it has not been added to the display list yet (so it's returned from with the itemToItemRenderer function). You shouldn't encounter this, but it's something to be aware of. I don't remember how we resolved this, if you run into it I'll try and dig up how we solved it.

           

          There are other approaches what you are trying to accomplish that you can take advantage of since you are using a custom item renderer, but start there for now and see how it goes. I haven't tried this in Flex 4, so I don't know if the same trick would work with the 4.5 DataGrid.

           

          Ben Schmidtke

          • 2. Re: Wait for Renderers to Display
            bucpatr1 Level 2

            Unfortunately that only helps if the item being edited happensto be in the first column of the datagrid since itemToRenderer() always returns the renderer of the first column for a datagrid.

            • 3. Re: Wait for Renderers to Display
              benschmidtke Level 1

              Yes, but if you combine that with other methods you can get where you need to go.

               

              var renderer:IListItemRenderer = dataGrid.itemToItemRenderer ( dataObjectToFind );

              if(renderer)

              {

                   var rowIndex:int = dataGrid.itemRendererToIndex( renderer );

                   var colIndex:int = columnDataFieldToIndex( dataFieldToFind );

               

                   // index null checks..

                   dataGrid.editedItemPosition = {columnIndex: colIndex, rowIndex: rowIndex };

              }

               

              Here is a example method for finding your column index for a datafield.

               

              public function columnDataFieldToIndex ( dataField:String ) : int

              {

                   var colIndex : int;

               

                   for each (var column:AdvancedDataGridColumn in columns)

                   {

                        if(column.dataField == dataField)

                        {

                             colIndex = columns.indexOf( column );

                             break;

                        }

                   }

               

                   return colIndex;

              }

               

              Hope that helps.