4
votes

I have a data grid that has a checkbox item renderer in a cloumn to allow row selections:

Main application:


<mx:DataGrid id="dg">
    <mx:columns>
        <mx:DataGridColumn id="ir" itemRenderer="renderers.RowCheckbox" /> 
        <mx:DataGridColumn dataField="Name" headerText="Name" /> 
    &lt/mx:columns>
</mx:DataGrid>

Item renderer:


<-- RowCheckbox -->
<?xml version="1.0" encoding="utf-8"?>
<mx:HBox xmlns:mx="http://www.adobe.com/2006/mxml" horizontalAlign="center"> 
    <mx:CheckBox id="chk"/>
</mx:HBox>

How can I get a handle to the item renderer / checkbox so that I may determine which rows are checked?

4

4 Answers

9
votes

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.

2
votes

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;
                }
            }
        }
0
votes

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.

-1
votes

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