Set Background-color for Headers of DataGrid

Marmalade-Cubes-256x256 Problem Summery: One of the BBS developers asked a question about setting the background-color of separate header of DataGrid component. At first, I guessed that the style headerColors of DataGrid would help us. However, this style controls all headers’ background-color. Does headerStyleName of DataGridColumn would help us? Unfortunately, the answer was no. Setting the “background-color” of the style “myDataGridColumnStyle” which I assigned to “headerStyleName” took no effect. No resolution? I googled a lot, found no existing resolution.

Solution Summery: At last, I determined to dig into the DataGrid and related classes to solve this problem. After a hard working, I got the answer by rewriting the DataGridColumn class and DataGridHeaderBackgroundSkin class. It’s really a perfect resolution in my opinion. Anyone finds a bug; please left your comment here. Thank you!

Search-256x256 Demo | DownloadDownload Full Project

Screenshot

clip_image002

Following is the source code of Catalog.as

  1. package
  2. {
  3.     public class Catalog
  4.     {
  5.        
  6.         public static function get cataglog():XMLList
  7.         {
  8.             return catalog..CD;
  9.         }
  10.        
  11.         private static var catalog:XML = <CATALOG>
  12.               <CD>
  13.                 <TITLE>Empire Burlesque</TITLE>
  14.                 <ARTIST>Bob Dylan</ARTIST>
  15.                 <COUNTRY>USA</COUNTRY>
  16.                 <COMPANY>Columbia</COMPANY>
  17.                 <PRICE>10.90</PRICE>
  18.                 <YEAR>1985</YEAR>
  19.               </CD>
  20.               <CD>
  21.                 <TITLE>Hide your heart</TITLE>
  22.                 <ARTIST>Bonnie Tylor</ARTIST>
  23.                 <COUNTRY>UK</COUNTRY>
  24.                 <COMPANY>CBS Records</COMPANY>
  25.                 <PRICE>9.90</PRICE>
  26.                 <YEAR>1988</YEAR>
  27.               </CD>
  28.               <CD>
  29.                 <TITLE>Greatest Hits</TITLE>
  30.                 <ARTIST>Dolly Parton</ARTIST>
  31.                 <COUNTRY>USA</COUNTRY>
  32.                 <COMPANY>RCA</COMPANY>
  33.                 <PRICE>9.90</PRICE>
  34.                 <YEAR>1982</YEAR>
  35.               </CD>
  36.               <CD>
  37.                 <TITLE>Still got the blues</TITLE>
  38.                 <ARTIST>Gary More</ARTIST>
  39.                 <COUNTRY>UK</COUNTRY>
  40.                 <COMPANY>Virgin redords</COMPANY>
  41.                 <PRICE>10.20</PRICE>
  42.                 <YEAR>1990</YEAR>
  43.               </CD>
  44.               <CD>
  45.                 <TITLE>Eros</TITLE>
  46.                 <ARTIST>Eros Ramazzotti</ARTIST>
  47.                 <COUNTRY>EU</COUNTRY>
  48.                 <COMPANY>BMG</COMPANY>
  49.                 <PRICE>9.90</PRICE>
  50.                 <YEAR>1997</YEAR>
  51.               </CD>
  52.               <CD>
  53.                 <TITLE>One night only</TITLE>
  54.                 <ARTIST>Bee Gees</ARTIST>
  55.                 <COUNTRY>UK</COUNTRY>
  56.                 <COMPANY>Polydor</COMPANY>
  57.                 <PRICE>10.90</PRICE>
  58.                 <YEAR>1998</YEAR>
  59.               </CD>
  60.               <CD>
  61.                 <TITLE>Sylvias Mother</TITLE>
  62.                 <ARTIST>Dr.Hook</ARTIST>
  63.                 <COUNTRY>UK</COUNTRY>
  64.                 <COMPANY>CBS</COMPANY>
  65.                 <PRICE>8.10</PRICE>
  66.                 <YEAR>1973</YEAR>
  67.               </CD>
  68.               <CD>
  69.                 <TITLE>Maggie May</TITLE>
  70.                 <ARTIST>Rod Stewart</ARTIST>
  71.                 <COUNTRY>UK</COUNTRY>
  72.                 <COMPANY>Pickwick</COMPANY>
  73.                 <PRICE>8.50</PRICE>
  74.                 <YEAR>1990</YEAR>
  75.               </CD>
  76.               <CD>
  77.                 <TITLE>Romanza</TITLE>
  78.                 <ARTIST>Andrea Bocelli</ARTIST>
  79.                 <COUNTRY>EU</COUNTRY>
  80.                 <COMPANY>Polydor</COMPANY>
  81.                 <PRICE>10.80</PRICE>
  82.                 <YEAR>1996</YEAR>
  83.               </CD>
  84.               <CD>
  85.                 <TITLE>When a man loves a woman</TITLE>
  86.                 <ARTIST>Percy Sledge</ARTIST>
  87.                 <COUNTRY>USA</COUNTRY>
  88.                 <COMPANY>Atlantic</COMPANY>
  89.                 <PRICE>8.70</PRICE>
  90.                 <YEAR>1987</YEAR>
  91.               </CD>
  92.               <CD>
  93.                 <TITLE>Black angel</TITLE>
  94.                 <ARTIST>Savage Rose</ARTIST>
  95.                 <COUNTRY>EU</COUNTRY>
  96.                 <COMPANY>Mega</COMPANY>
  97.                 <PRICE>10.90</PRICE>
  98.                 <YEAR>1995</YEAR>
  99.               </CD>
  100.               <CD>
  101.                 <TITLE>1999 Grammy Nominees</TITLE>
  102.                 <ARTIST>Many</ARTIST>
  103.                 <COUNTRY>USA</COUNTRY>
  104.                 <COMPANY>Grammy</COMPANY>
  105.                 <PRICE>10.20</PRICE>
  106.                 <YEAR>1999</YEAR>
  107.               </CD>
  108.               <CD>
  109.                 <TITLE>For the good times</TITLE>
  110.                 <ARTIST>Kenny Rogers</ARTIST>
  111.                 <COUNTRY>UK</COUNTRY>
  112.                 <COMPANY>Mucik Master</COMPANY>
  113.                 <PRICE>8.70</PRICE>
  114.                 <YEAR>1995</YEAR>
  115.               </CD>
  116.               <CD>
  117.                 <TITLE>Big Willie style</TITLE>
  118.                 <ARTIST>Will Smith</ARTIST>
  119.                 <COUNTRY>USA</COUNTRY>
  120.                 <COMPANY>Columbia</COMPANY>
  121.                 <PRICE>9.90</PRICE>
  122.                 <YEAR>1997</YEAR>
  123.               </CD>
  124.               <CD>
  125.                 <TITLE>Tupelo Honey</TITLE>
  126.                 <ARTIST>Van Morrison</ARTIST>
  127.                 <COUNTRY>UK</COUNTRY>
  128.                 <COMPANY>Polydor</COMPANY>
  129.                 <PRICE>8.20</PRICE>
  130.                 <YEAR>1971</YEAR>
  131.               </CD>
  132.               <CD>
  133.                 <TITLE>Soulsville</TITLE>
  134.                 <ARTIST>Jorn Hoel</ARTIST>
  135.                 <COUNTRY>Norway</COUNTRY>
  136.                 <COMPANY>WEA</COMPANY>
  137.                 <PRICE>7.90</PRICE>
  138.                 <YEAR>1996</YEAR>
  139.               </CD>
  140.               <CD>
  141.                 <TITLE>The very best of</TITLE>
  142.                 <ARTIST>Cat Stevens</ARTIST>
  143.                 <COUNTRY>UK</COUNTRY>
  144.                 <COMPANY>Island</COMPANY>
  145.                 <PRICE>8.90</PRICE>
  146.                 <YEAR>1990</YEAR>
  147.               </CD>
  148.               <CD>
  149.                 <TITLE>Stop</TITLE>
  150.                 <ARTIST>Sam Brown</ARTIST>
  151.                 <COUNTRY>UK</COUNTRY>
  152.                 <COMPANY>A and M</COMPANY>
  153.                 <PRICE>8.90</PRICE>
  154.                 <YEAR>1988</YEAR>
  155.               </CD>
  156.               <CD>
  157.                 <TITLE>Bridge of Spies</TITLE>
  158.                 <ARTIST>T`Pau</ARTIST>
  159.                 <COUNTRY>UK</COUNTRY>
  160.                 <COMPANY>Siren</COMPANY>
  161.                 <PRICE>7.90</PRICE>
  162.                 <YEAR>1987</YEAR>
  163.               </CD>
  164.               <CD>
  165.                 <TITLE>Private Dancer</TITLE>
  166.                 <ARTIST>Tina Turner</ARTIST>
  167.                 <COUNTRY>UK</COUNTRY>
  168.                 <COMPANY>Capitol</COMPANY>
  169.                 <PRICE>8.90</PRICE>
  170.                 <YEAR>1983</YEAR>
  171.               </CD>
  172.               <CD>
  173.                 <TITLE>Midt om natten</TITLE>
  174.                 <ARTIST>Kim Larsen</ARTIST>
  175.                 <COUNTRY>EU</COUNTRY>
  176.                 <COMPANY>Medley</COMPANY>
  177.                 <PRICE>7.80</PRICE>
  178.                 <YEAR>1983</YEAR>
  179.               </CD>
  180.               <CD>
  181.                 <TITLE>Pavarotti Gala Concert</TITLE>
  182.                 <ARTIST>Luciano Pavarotti</ARTIST>
  183.                 <COUNTRY>UK</COUNTRY>
  184.                 <COMPANY>DECCA</COMPANY>
  185.                 <PRICE>9.90</PRICE>
  186.                 <YEAR>1991</YEAR>
  187.               </CD>
  188.               <CD>
  189.                 <TITLE>The dock of the bay</TITLE>
  190.                 <ARTIST>Otis Redding</ARTIST>
  191.                 <COUNTRY>USA</COUNTRY>
  192.                 <COMPANY>Atlantic</COMPANY>
  193.                 <PRICE>7.90</PRICE>
  194.                 <YEAR>1987</YEAR>
  195.               </CD>
  196.               <CD>
  197.                 <TITLE>Picture book</TITLE>
  198.                 <ARTIST>Simply Red</ARTIST>
  199.                 <COUNTRY>EU</COUNTRY>
  200.                 <COMPANY>Elektra</COMPANY>
  201.                 <PRICE>7.20</PRICE>
  202.                 <YEAR>1985</YEAR>
  203.               </CD>
  204.               <CD>
  205.                 <TITLE>Red</TITLE>
  206.                 <ARTIST>The Communards</ARTIST>
  207.                 <COUNTRY>UK</COUNTRY>
  208.                 <COMPANY>London</COMPANY>
  209.                 <PRICE>7.80</PRICE>
  210.                 <YEAR>1987</YEAR>
  211.               </CD>
  212.               <CD>
  213.                 <TITLE>Unchain my heart</TITLE>
  214.                 <ARTIST>Joe Cocker</ARTIST>
  215.                 <COUNTRY>USA</COUNTRY>
  216.                 <COMPANY>EMI</COMPANY>
  217.                 <PRICE>8.20</PRICE>
  218.                 <YEAR>1987</YEAR>
  219.               </CD>
  220.             </CATALOG>;
  221.     }
  222. }

And following is the source code of DataGridColumn.as

  1. package com.edison.controls.dataGridClasses 
  2. {
  3.     import flash.events.Event;
  4.    
  5.     import mx.controls.dataGridClasses.DataGridColumn;
  6.     import mx.core.mx_internal;
  7.     import mx.utils.UIDUtil;
  8.     use namespace mx_internal;
  9.    
  10.     [Style(name="headerColors", type="Array", arrayType="uint", format="Color", inherit="yes")]
  11.     public dynamic class DataGridColumn extends mx.controls.dataGridClasses.DataGridColumn
  12.     {
  13.         public function DataGridColumn(columnName:String=null)
  14.         {
  15.             super(columnName);
  16.         }
  17.        
  18.         public var uid:String = UIDUtil.createUID();
  19.        
  20.         override mx_internal function setWidth(value:Number):void
  21.         {
  22.             super.setWidth(value);
  23.             dispatchEvent(new Event("widthChanged"));
  24.         }
  25.     }
  26. }

Following is the source code of DataGridHeaderBackgroundSkin.as

  1. package com.edison.skins
  2. {
  3.     import flash.display.GradientType;
  4.     import flash.display.Graphics;
  5.     import flash.display.Sprite;
  6.     import flash.events.Event;
  7.     import flash.geom.Matrix;
  8.    
  9.     import mx.controls.DataGrid;
  10.     import mx.controls.dataGridClasses.DataGridColumn;
  11.     import mx.controls.dataGridClasses.DataGridHeader;
  12.     import mx.controls.listClasses.IListItemRenderer;
  13.     import mx.core.mx_internal;
  14.     import mx.skins.halo.DataGridHeaderBackgroundSkin;
  15.     import mx.styles.StyleManager;
  16.     import mx.utils.UIDUtil;
  17.     use namespace mx_internal;
  18.    
  19.     public class DataGridHeaderBackgroundSkin extends mx.skins.halo.DataGridHeaderBackgroundSkin
  20.     {
  21.         public function DataGridHeaderBackgroundSkin()
  22.         {
  23.             super();
  24.         }
  25.        
  26.         private var columnBackgroundMap:Object = new Object();
  27.        
  28.         override protected function updateDisplayList(w:Number, h:Number):void
  29.         {
  30.             super.updateDisplayList(w,h);
  31.            
  32.             if(w == 0)
  33.                 return;
  34.                
  35.             var dataGridHeader:DataGridHeader = DataGridHeader(parent.parent);
  36.             var dataGrid:DataGrid = DataGrid(dataGridHeader.owner);
  37.             var visibleColumns:Array = dataGrid.getAllVisibleColumns();
  38.             var headerItems:Array = dataGridHeader.rendererArray;
  39.            
  40.             for each(var column:DataGridColumn in visibleColumns)
  41.             {               
  42.                 var colors:Array = column.getStyle("headerColors");
  43.                 var headerItem:IListItemRenderer = headerItems[column.colNum]               
  44.                 var x:Number = headerItem.x;
  45.                 w = column.width;
  46.                
  47.                 var uid:String = UIDUtil.getUID(column);
  48.                 var sprite:Sprite = columnBackgroundMap[uid];
  49.                 if(sprite == null)
  50.                 {
  51.                     sprite = new Sprite();
  52.                     parent.addChild(sprite);                   
  53.                     columnBackgroundMap[uid] = sprite;
  54.                 }               
  55.                 sprite.x = x;
  56.                
  57.                 if(colors != null)
  58.                 {           
  59.                     var g:Graphics = sprite.graphics;
  60.                     g.clear();
  61.                     var matrix:Matrix = new Matrix();
  62.                     matrix.createGradientBox(w, h + 1, Math.PI/2, 0, 0);
  63.                    
  64.                     StyleManager.getColorNames(colors);
  65.                     colors = [ colors[0], colors[0], colors[1] ];
  66.                     var ratios:Array = [ 0, 60, 255 ];
  67.                     var alphas:Array = [ 1.0, 1.0, 1.0 ];
  68.                    
  69.                     g.beginGradientFill(GradientType.LINEAR, colors, alphas, ratios, matrix);
  70.                     g.lineStyle(0, 0x000000, 0);
  71.                     g.moveTo(0, 0);
  72.                     g.lineTo(w, 0);
  73.                     g.lineTo(w, h - 0.5);
  74.                     g.lineStyle(0, getStyle("borderColor"), 100);
  75.                     g.lineTo(0, h - 0.5);
  76.                     g.lineStyle(0, 0x000000, 0);
  77.                     g.endFill();
  78.                 }
  79.                
  80.                 column.addEventListener("widthChanged",columnWidthChangedHandler);
  81.             }
  82.         }
  83.        
  84.         private function columnWidthChangedHandler(event:Event):void
  85.         {
  86.             invalidateDisplayList();
  87.         }
  88.     }
  89. }

Last one is the source code of DataGridHeaderBackgroundProblem.mxml

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <mx:Application 
  3.     xmlns:mx="http://www.adobe.com/2006/mxml"
  4.     xmlns:dataGridClasses="com.edison.controls.dataGridClasses.*" 
  5.     layout="absolute" >
  6.     <mx:Panel 
  7.         title="Set Background-color for Headers of DataGrid"
  8.         width="100%"
  9.         height="100%">
  10.         <mx:DataGrid 
  11.             dataProvider="{Catalog.cataglog}" 
  12.             headerBackgroundSkin="com.edison.skins.DataGridHeaderBackgroundSkin"
  13.             height="100%"
  14.             >
  15.             <mx:columns>
  16.                 <dataGridClasses:DataGridColumn dataField="ARTIST" headerText="Artist" headerColors="{[0xFF9900,0xFFFFFF]}"/>
  17.                 <dataGridClasses:DataGridColumn dataField="TITLE" headerText="Title" headerColors="{[0x99FF00,0xFFFFFF]}"/>
  18.                 <dataGridClasses:DataGridColumn dataField="YEAR" headerText="Year" headerColors="{[0x0099FF,0xFFFFFF]}"/>
  19.             </mx:columns>
  20.         </mx:DataGrid>
  21.     </mx:Panel>
  22. </mx:Application>
Share and Enjoy:
  • Digg
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • DZone
  • Reddit
  • Technorati
  • StumbleUpon
  • Twitter
RSS Enjoy this Post? Subscribe to Ntt.cc

RSS Feed   RSS Feed     Email Feed  Email Feed
You can leave a response, or trackback from your own site.

12 Responses to “Set Background-color for Headers of DataGrid”

  1. [...] 之前介绍过Flex中设置DataGrid背景颜色的例子(Flex中利用backgroundColor样式设置DataGrid控件每一个DataGridColumn对象背景颜色的例子)以及Flex中如何实现DataGrid控件头部高度等例子,在Set Background-color for Headers of DataGrid,介绍了如何实现自定义DataGrid头部背景颜色,有需要的可以下来直接用。下面是效果图: [...]

  2. [...] Article URL: Set Background-color for Headers of DataGrid [...]

  3. Fernando says:

    Very useful, thx ;)

  4. Daniel says:

    SOOOO helpful! Thanks a million… Nay! a billion!! ;)

  5. SigmundD says:

    Thank’s! Amazing!

  6. Ptiteshina says:

    Thank you very much for this work ! It is very useful and don t exist another answer of this question on the web :)

  7. Louis says:

    Very Useful. But when i set lockedColumnCount, the datagrid is not showing. Can anyone help me. Thanks.

  8. Varun Vijaywargi says:

    It is useful. Thanks a lot.
    But when we set lockedColumnCount, it does not work.

    Please provide a solution with a grid using the lockedColumnCount. Thanks

  9. BrunoJCM says:

    Yes, unfortunately it’s true..
    Setting lockedColumnCount >= 1 breaks this.
    I’m trying to solve, if I got a solution, I will post.

  10. BrunoJCM says:

    Firstly, the original post have a performance issue, the listener were added a lot of times to the same DataGridColumn. To fix this, I did:

    On the ExtendedDataGridColumn, I put a new property as folows:

    var isSkinEventListenerSet: Boolean = false;

    and changed the addEventListener line on the skin to:

    if (column is ExtendedDataGridColumn)
    {
    if (! ExtendedDataGridColumn(column).isSkinEventListenerSet)
    {
    column.addEventListener(”widthChanged”,columnWidthChangedHandler);
    ExtendedDataGridColumn(column).isSkinEventListenerSet = true;
    }
    }

    To solve the lockedColumnCount problem, I did:

    On the datagrid, I put a method like this:

    protected function onScroll(event: ScrollEvent):void {
    if (event.direction = ScrollEventDirection.HORIZONTAL)
    {
    datagrid.columns[datagrid.lockedColumnCount].dispatchEvent(new Event(”widthChanged”));
    datagrid.columns[0].dispatchEvent(new Event(”widthChanged”));
    }
    }

    And on the initialization of the Datagrid, I put:

    datagrid.addEventListener(Event.SCROLL, onScroll);

    Sorry for the lack of code formatting and coloring, I don’t know how to do that here…
    This worked ok for me, I hope it works for you too. Thanks!

  11. minidxer says:

    @BrunoJCM
    Great work! Thanks a lot!!!

  12. BrunoJCM says:

    Oh, There’s a bug in my code!

    Line
    ———————
    if (event.direction = ScrollEventDirection.HORIZONTAL)
    ———————

    Should be
    ———————
    if (event.direction == ScrollEventDirection.HORIZONTAL)
    ———————

    And I realized I had modified another piece of the original code, but I don’t know if it’s necessary:

    Instead of
    ———————
    var colors:Array = column.getStyle(”headerColors”);
    var headerItem:IListItemRenderer = headerItems[column.colNum]
    ———————

    I put
    ———————
    var headerItem:IListItemRenderer = null;
    for each(var possibleHeaderItem:DataGridItemRenderer in headerItems)
    {
    if ( column == possibleHeaderItem.data)
    {
    headerItem = possibleHeaderItem;
    }
    }
    ———————

    I think it’s the same (slowly), but I have no time to test it now.. :P

Leave a Reply