textRollOverColor in Flex DataGrid

According to Adobe's documentation, the Flex DataGrid control supports the textRollOverColor CSS property. But this past week I discovered that this is not the case :( A quick search revealed that I'm not alone in this discovery, but it seems that no one has proposed a useful solution yet... so I went about creating my own :)

So, why doesn't it work as documented? Well, a quick check revealed that the relevant text colors are supposed to be set in the DataGridItemRenderer's validateNow() method. That method sets the item's explicitColor property, and then calls the super.validateNow() method to update the display. However, the super (UITextField) class' validateNow() method does not update the text format unless the styleChangedFlag property is set - but that flag is not being set. Since the styleChangedFlag property is marked as private, I can only assume that it is meant to be set by the relevant setter functions, but as there is no setter function for the explicitColor property, the styleChangedFlag is not set.

So, what to do about it? Well, I found easiest solution was to write a custom DataGridItemRender that overrides the super class' validateNow() method. The new validateNow() method looks like this:

override public function validateNow():void {
  if (data && parent && !(data as DataGridColumn)) {
    var dg:DataGrid = DataGrid(listData.owner);
    if (dg.isItemHighlighted(listData.uid))
      textColor = getStyle("textRollOverColor");
    else if (dg.isItemSelected(listData.uid))
      textColor = getStyle("textSelectedColor");
    else textColor = getStyle("color");

It's pretty straight-forward - based very closely on the DataGridItemRenderer's validateNow() method, but instead of setting the item's explicitColor property, it goes straight ahead and sets the underlying text field's color directly. You might also notice the reference to the textSelectedColor style - it turns out that one was also broken, but this override fixes it too.

Something you won't find in the DataGridItemRenderer's validateNow() method is the reference to the "data as DataGridColumn" clause at the end of the first if statement... I won't go into the details now, but this custom renderer won't help for DataGrid header items, and so that clause prevents this override from doing anything to header items. In short, validateNow() is almost never called for DataGrid header items, so they have to be treated specially.

Well, that's it for now... in my next post I will show how to fix the DataGrid header items (need a custom DataGrid control), and link to a demo app that you can test, and view the source of :)

comments powered by Disqus