DataGrid highlights wrong row
Problem:
You have a DataGrid which is highlighting the wrong row when you navigate using the mouse or keyboard.
Solution:
It is likely that you have put duplicate data in the dataProvider for your DataGrid. It is illegal to put the same instance into the collection of data that you assign to the dataProvider property. You can create duplicate objects, but they must be different instances of the same object. It is valid if the fields are identical, but not the objects themselves.
The only solution to this is to create unique objects for your DataGrid.
Further explanation, along with a SWF example and source code:
Example:
You can clearly see the incorrect behavior here. View Source is enabled and you can view this in its own page DataGrid highlights wrong row example. Roll over the first row and the DataGrid will highlight the third row:
This is the definition of the data. Notice that obj1 is inserted into the array twice:
-
var array:Array = [];
-
var obj1:Object = {title:"The Ham", author:"Harold James"};
-
var obj2:Object = {title:"Hoodilly's", author:"Harold James"};
-
var obj3:Object = {title:"Kill-a-man-jaro", author:"Chuck Johnson"};
-
array.push(obj1, obj2, obj1, obj3);
-
dupData = new ArrayCollection(array);
Explanation:
The DataGrid indexes its data using a UID that is created for each row of data in the dataProvider. The DataGrid gets the UID for each row by calling UIDUtil.getUID(item:Object). The UID returned is a String. See the entry on UIDUtil for more information on the generation method.
The DataGrid and its associated classes keep several hashes that are indexed by the UID of the row. These are instances of Object that contain the UIDs. For example, ListBaseContentHolder has a visibleData hash that maps the row to item renderer when the row is visible. ListBase (parent class of DataGrid) also stores the UIDs of objects such as the highlightUID and caretUID.
Clearly code such as this, in DataGridBase, can only return a single item renderer for each UID and therefore will behave incorrectly when your data contains duplicate instances:
-
override protected function UIDToItemRenderer(uid:String):IListItemRenderer
-
{
-
var r:IListItemRenderer = visibleData[uid];
-
if (!r)
-
{
-
if (lockedRowContent)
-
r = lockedRowContent.visibleData[uid];
-
}
-
if (!r)
-
{
-
if (lockedColumnContent)
-
r = lockedColumnContent.visibleData[uid];
-
}
-
if (!r)
-
{
-
if (lockedColumnAndRowContent)
-
r = lockedColumnAndRowContent.visibleData[uid];
-
}
-
return r;
-
}
This isn't the only example, there is a great deal of code relating to lists that relies on this assumption.
