A: 

You can use the indexToItemRenderer() method exposed by all subclasses of ListBase.

For example:

private function someFunction(index:int):void
{
    var rowCheckbox:RowCheckbox = dg.indexToItemRenderer(index) as RowCheckbox;
    trace(rowCheckbox.chk.selected.toString());
}

... where index represents the index of the DataGrid item whose "chk" property you want test.

Christian Nunciato
I don't think this will work with multiple item renderers in diffrent columns, say I need the renderer in another column, how can I do that?
mmattax
Good point, yes. Christophe's answer is actually better; I've used the above approach on single-column, non-scrolling lists and had good results, but what you're really looking for is neither a property of the underlying data nor of the visible display objects, but rather something in the middle.
Christian Nunciato
You could modify your above function to check both the row and column of the custom Renderer... someFunction(row:int,cell:int):void
AndrewB
+3  A: 

Just a word of advice: We had a similar problem in our application and we solved it by adding a "selected" property to the entities in the dataprovider of the datagrid. The selected property of the checkBox was then bound to the selected property of our entity. To know which ones were selected, we just looped over the entities in the dataprovider instead of the item renderers. After a lot of different approaches, this really was the best option.

If I remember correctly, the problem was that the itemrenderers did not remember the selected state correctly and the datagrid was completely messed up when you scrolled up and down. The wrong rows were selected after scrolling.

Another option would be to dispatch an event in the item renderer which bubbles up all the way to the control hosting the datagrid. You could then listen for these events and update your model to reflect the changes.

Christophe Herreman
This raises an excellent point. In my zeal it looks like I missed what the poster was really asking; indeed this seems like a sound way to go, because you're right, renderers are reused, and that reuse could have unintuitive and unintended consequences. +1
Christian Nunciato
We've used that approach as well and I'd agree it's probably the easiest.
cliff.meyers
This is probably the easiest and most elegant solution ( as It is completely compliant with OOP encapsulation rules) we have came up with.
Chepech
This is a good way to go about it if you don't mind having other crap in your data. If you *do* want to go about it the hard way you can use the visibleData property on the DataGrid to parse which rows should be selected out of the currently visible rows. Then, when the datagrid is scrolled, re-evaluate which rows should be selected.
Jonathan Dumaine
+1  A: 

I ran into similar issues with the DataGrid and multiple item renderers and the reuse of item renderers when scrolling. In order to access DataGrid item renderers I extended the DataGrid. My first thought was to use the indicesToIndex() followed by indexToItemRenderer(). Unfortunately these methods didn't do what I expected so I added the indicesToItemRenderer() method:

package com.whatever.controls {

import mx.controls.DataGrid;
import mx.controls.listClasses.IListItemRenderer;

public class CustomDataGrid extends DataGrid
{

 public function CustomDataGrid()
 {
  super();
 }

    public function indicesToItemRenderer(rowIndex:int, colIndex:int):IListItemRenderer
    {
     var firstItemIndex:int = verticalScrollPosition - offscreenExtraRowsTop;
        if (rowIndex < firstItemIndex ||
         rowIndex >= firstItemIndex + listItems.length
         )
        {
         return null;
        }

     return listItems[rowIndex - firstItemIndex][colIndex];
    }

}

To resolve the reused item renderers when scrolling issue, refer to this article:

http://www.adobe.com/devnet/flex/articles/itemrenderers_pt1.html

It boils down to overriding the data setter and storing properties in data. For example, I had one column using a CheckBox itemRenderer and another column using ComboBox. For both I listen for the change event and store selected, selectedIndex, etc in data whenever properties change and override the data setter to set those properties:

  override public function set data(value:Object):void
  {
   if (value != null)
   {
    super.data = value;

    if (data.hasOwnProperty('selected') && data.selected)
    {
     selected = data.selected;
    }
    else
    {
     selected = false;
    }
   }
  }
Mark Tomsu
FANTASTIC. The indicesToItemRenderer() function was exactly what I was looking for. I Can't believe there isn't something like that already on DataGridBase since ListBase's indexToItemRenderer() doesn't take into account columns! Thanks.
Jonathan Dumaine
A: 

In the ItemRenderer, try putting Checkbox Component in a VBox..resolves the scrolling issue.

himanshu