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

package
{
    public class Catalog
    {

        public static function get cataglog():XMLList
        {
            return catalog..CD;
        }

        private static var catalog:XML = <CATALOG>
              <CD>
                <TITLE>Empire Burlesque</TITLE>
                <ARTIST>Bob Dylan</ARTIST>
                <COUNTRY>USA</COUNTRY>
                <COMPANY>Columbia</COMPANY>
                <PRICE>10.90</PRICE>
                <YEAR>1985</YEAR>
              </CD>
              <CD>
                <TITLE>Hide your heart</TITLE>
                <ARTIST>Bonnie Tylor</ARTIST>
                <COUNTRY>UK</COUNTRY>
                <COMPANY>CBS Records</COMPANY>
                <PRICE>9.90</PRICE>
                <YEAR>1988</YEAR>
              </CD>
              <CD>
                <TITLE>Greatest Hits</TITLE>
                <ARTIST>Dolly Parton</ARTIST>
                <COUNTRY>USA</COUNTRY>
                <COMPANY>RCA</COMPANY>
                <PRICE>9.90</PRICE>
                <YEAR>1982</YEAR>
              </CD>
              <CD>
                <TITLE>Still got the blues</TITLE>
                <ARTIST>Gary More</ARTIST>
                <COUNTRY>UK</COUNTRY>
                <COMPANY>Virgin redords</COMPANY>
                <PRICE>10.20</PRICE>
                <YEAR>1990</YEAR>
              </CD>
              <CD>
                <TITLE>Eros</TITLE>
                <ARTIST>Eros Ramazzotti</ARTIST>
                <COUNTRY>EU</COUNTRY>
                <COMPANY>BMG</COMPANY>
                <PRICE>9.90</PRICE>
                <YEAR>1997</YEAR>
              </CD>
              <CD>
                <TITLE>One night only</TITLE>
                <ARTIST>Bee Gees</ARTIST>
                <COUNTRY>UK</COUNTRY>
                <COMPANY>Polydor</COMPANY>
                <PRICE>10.90</PRICE>
                <YEAR>1998</YEAR>
              </CD>
              <CD>
                <TITLE>Sylvias Mother</TITLE>
                <ARTIST>Dr.Hook</ARTIST>
                <COUNTRY>UK</COUNTRY>
                <COMPANY>CBS</COMPANY>
                <PRICE>8.10</PRICE>
                <YEAR>1973</YEAR>
              </CD>
              <CD>
                <TITLE>Maggie May</TITLE>
                <ARTIST>Rod Stewart</ARTIST>
                <COUNTRY>UK</COUNTRY>
                <COMPANY>Pickwick</COMPANY>
                <PRICE>8.50</PRICE>
                <YEAR>1990</YEAR>
              </CD>
              <CD>
                <TITLE>Romanza</TITLE>
                <ARTIST>Andrea Bocelli</ARTIST>
                <COUNTRY>EU</COUNTRY>
                <COMPANY>Polydor</COMPANY>
                <PRICE>10.80</PRICE>
                <YEAR>1996</YEAR>
              </CD>
              <CD>
                <TITLE>When a man loves a woman</TITLE>
                <ARTIST>Percy Sledge</ARTIST>
                <COUNTRY>USA</COUNTRY>
                <COMPANY>Atlantic</COMPANY>
                <PRICE>8.70</PRICE>
                <YEAR>1987</YEAR>
              </CD>
              <CD>
                <TITLE>Black angel</TITLE>
                <ARTIST>Savage Rose</ARTIST>
                <COUNTRY>EU</COUNTRY>
                <COMPANY>Mega</COMPANY>
                <PRICE>10.90</PRICE>
                <YEAR>1995</YEAR>
              </CD>
              <CD>
                <TITLE>1999 Grammy Nominees</TITLE>
                <ARTIST>Many</ARTIST>
                <COUNTRY>USA</COUNTRY>
                <COMPANY>Grammy</COMPANY>
                <PRICE>10.20</PRICE>
                <YEAR>1999</YEAR>
              </CD>
              <CD>
                <TITLE>For the good times</TITLE>
                <ARTIST>Kenny Rogers</ARTIST>
                <COUNTRY>UK</COUNTRY>
                <COMPANY>Mucik Master</COMPANY>
                <PRICE>8.70</PRICE>
                <YEAR>1995</YEAR>
              </CD>
              <CD>
                <TITLE>Big Willie style</TITLE>
                <ARTIST>Will Smith</ARTIST>
                <COUNTRY>USA</COUNTRY>
                <COMPANY>Columbia</COMPANY>
                <PRICE>9.90</PRICE>
                <YEAR>1997</YEAR>
              </CD>
              <CD>
                <TITLE>Tupelo Honey</TITLE>
                <ARTIST>Van Morrison</ARTIST>
                <COUNTRY>UK</COUNTRY>
                <COMPANY>Polydor</COMPANY>
                <PRICE>8.20</PRICE>
                <YEAR>1971</YEAR>
              </CD>
              <CD>
                <TITLE>Soulsville</TITLE>
                <ARTIST>Jorn Hoel</ARTIST>
                <COUNTRY>Norway</COUNTRY>
                <COMPANY>WEA</COMPANY>
                <PRICE>7.90</PRICE>
                <YEAR>1996</YEAR>
              </CD>
              <CD>
                <TITLE>The very best of</TITLE>
                <ARTIST>Cat Stevens</ARTIST>
                <COUNTRY>UK</COUNTRY>
                <COMPANY>Island</COMPANY>
                <PRICE>8.90</PRICE>
                <YEAR>1990</YEAR>
              </CD>
              <CD>
                <TITLE>Stop</TITLE>
                <ARTIST>Sam Brown</ARTIST>
                <COUNTRY>UK</COUNTRY>
                <COMPANY>A and M</COMPANY>
                <PRICE>8.90</PRICE>
                <YEAR>1988</YEAR>
              </CD>
              <CD>
                <TITLE>Bridge of Spies</TITLE>
                <ARTIST>T`Pau</ARTIST>
                <COUNTRY>UK</COUNTRY>
                <COMPANY>Siren</COMPANY>
                <PRICE>7.90</PRICE>
                <YEAR>1987</YEAR>
              </CD>
              <CD>
                <TITLE>Private Dancer</TITLE>
                <ARTIST>Tina Turner</ARTIST>
                <COUNTRY>UK</COUNTRY>
                <COMPANY>Capitol</COMPANY>
                <PRICE>8.90</PRICE>
                <YEAR>1983</YEAR>
              </CD>
              <CD>
                <TITLE>Midt om natten</TITLE>
                <ARTIST>Kim Larsen</ARTIST>
                <COUNTRY>EU</COUNTRY>
                <COMPANY>Medley</COMPANY>
                <PRICE>7.80</PRICE>
                <YEAR>1983</YEAR>
              </CD>
              <CD>
                <TITLE>Pavarotti Gala Concert</TITLE>
                <ARTIST>Luciano Pavarotti</ARTIST>
                <COUNTRY>UK</COUNTRY>
                <COMPANY>DECCA</COMPANY>
                <PRICE>9.90</PRICE>
                <YEAR>1991</YEAR>
              </CD>
              <CD>
                <TITLE>The dock of the bay</TITLE>
                <ARTIST>Otis Redding</ARTIST>
                <COUNTRY>USA</COUNTRY>
                <COMPANY>Atlantic</COMPANY>
                <PRICE>7.90</PRICE>
                <YEAR>1987</YEAR>
              </CD>
              <CD>
                <TITLE>Picture book</TITLE>
                <ARTIST>Simply Red</ARTIST>
                <COUNTRY>EU</COUNTRY>
                <COMPANY>Elektra</COMPANY>
                <PRICE>7.20</PRICE>
                <YEAR>1985</YEAR>
              </CD>
              <CD>
                <TITLE>Red</TITLE>
                <ARTIST>The Communards</ARTIST>
                <COUNTRY>UK</COUNTRY>
                <COMPANY>London</COMPANY>
                <PRICE>7.80</PRICE>
                <YEAR>1987</YEAR>
              </CD>
              <CD>
                <TITLE>Unchain my heart</TITLE>
                <ARTIST>Joe Cocker</ARTIST>
                <COUNTRY>USA</COUNTRY>
                <COMPANY>EMI</COMPANY>
                <PRICE>8.20</PRICE>
                <YEAR>1987</YEAR>
              </CD>
            </CATALOG>;
    }
}

And following is the source code of DataGridColumn.as

package com.edison.controls.dataGridClasses
{
	import flash.events.Event;

	import mx.controls.dataGridClasses.DataGridColumn;
	import mx.core.mx_internal;
	import mx.utils.UIDUtil;
	use namespace mx_internal;

	[Style(name="headerColors", type="Array", arrayType="uint", format="Color", inherit="yes")]
	public dynamic class DataGridColumn extends mx.controls.dataGridClasses.DataGridColumn
	{
		public function DataGridColumn(columnName:String=null)
		{
			super(columnName);
		}

		public var uid:String = UIDUtil.createUID();

		override mx_internal function setWidth(value:Number):void
	    {
	        super.setWidth(value);
	        dispatchEvent(new Event("widthChanged"));
	    }
	}
}

Following is the source code of DataGridHeaderBackgroundSkin.as

package com.edison.skins
{
	import flash.display.GradientType;
	import flash.display.Graphics;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.geom.Matrix;

	import mx.controls.DataGrid;
	import mx.controls.dataGridClasses.DataGridColumn;
	import mx.controls.dataGridClasses.DataGridHeader;
	import mx.controls.listClasses.IListItemRenderer;
	import mx.core.mx_internal;
	import mx.skins.halo.DataGridHeaderBackgroundSkin;
	import mx.styles.StyleManager;
	import mx.utils.UIDUtil;
	use namespace mx_internal;

	public class DataGridHeaderBackgroundSkin extends mx.skins.halo.DataGridHeaderBackgroundSkin
	{
		public function DataGridHeaderBackgroundSkin()
		{
			super();
		}

		private var columnBackgroundMap:Object = new Object();

		override protected function updateDisplayList(w:Number, h:Number):void
		{
			super.updateDisplayList(w,h);

			if(w == 0)
				return;

			var dataGridHeader:DataGridHeader = DataGridHeader(parent.parent);
			var dataGrid:DataGrid = DataGrid(dataGridHeader.owner);
			var visibleColumns:Array = dataGrid.getAllVisibleColumns();
			var headerItems:Array = dataGridHeader.rendererArray;

			for each(var column:DataGridColumn in visibleColumns)
			{
				var colors:Array = column.getStyle("headerColors");
				var headerItem:IListItemRenderer = headerItems[column.colNum]
				var x:Number = headerItem.x;
				w = column.width;

				var uid:String = UIDUtil.getUID(column);
				var sprite:Sprite = columnBackgroundMap[uid];
				if(sprite == null)
				{
					sprite = new Sprite();
					parent.addChild(sprite);
					columnBackgroundMap[uid] = sprite;
				}
				sprite.x = x;

				if(colors != null)
				{
					var g:Graphics = sprite.graphics;
					g.clear();
					var matrix:Matrix = new Matrix();
					matrix.createGradientBox(w, h + 1, Math.PI/2, 0, 0);

					StyleManager.getColorNames(colors);
					colors = [ colors[0], colors[0], colors[1] ];
					var ratios:Array = [ 0, 60, 255 ];
					var alphas:Array = [ 1.0, 1.0, 1.0 ];

					g.beginGradientFill(GradientType.LINEAR, colors, alphas, ratios, matrix);
					g.lineStyle(0, 0x000000, 0);
					g.moveTo(0, 0);
					g.lineTo(w, 0);
					g.lineTo(w, h - 0.5);
					g.lineStyle(0, getStyle("borderColor"), 100);
					g.lineTo(0, h - 0.5);
					g.lineStyle(0, 0x000000, 0);
					g.endFill();
				}

				column.addEventListener("widthChanged",columnWidthChangedHandler);
			}
		}

		private function columnWidthChangedHandler(event:Event):void
		{
			invalidateDisplayList();
		}
	}
}

Last one is the source code of DataGridHeaderBackgroundProblem.mxml

<?xml version="1.0" encoding="utf-8"?>
<mx:Application
	xmlns:mx="http://www.adobe.com/2006/mxml"
	xmlns:dataGridClasses="com.edison.controls.dataGridClasses.*"
	layout="absolute" >
	<mx:Panel
		title="Set Background-color for Headers of DataGrid"
		width="100%"
		height="100%">
		<mx:DataGrid
			dataProvider="{Catalog.cataglog}"
			headerBackgroundSkin="com.edison.skins.DataGridHeaderBackgroundSkin"
			height="100%"
			>
			<mx:columns>
				<dataGridClasses:DataGridColumn dataField="ARTIST" headerText="Artist" headerColors="{[0xFF9900,0xFFFFFF]}"/>
	            <dataGridClasses:DataGridColumn dataField="TITLE" headerText="Title" headerColors="{[0x99FF00,0xFFFFFF]}"/>
	            <dataGridClasses:DataGridColumn dataField="YEAR" headerText="Year" headerColors="{[0x0099FF,0xFFFFFF]}"/>
			</mx:columns>
		</mx:DataGrid>
	</mx:Panel>
</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 Follow us Follow us
You can leave a response, or trackback from your own site.

16 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

  13. Ced says:

    Nice, but not perfect though. It doesn’t work when you use horizontal scroll.

  14. [...] have introduced how to set background color for the headers of DataGrid in Flex, sometimes, we also need to get the row and column value in DataGrid, do you know how to do it? The [...]

  15. prith says:

    Hi,

    thanks a lot , for the solution , the gradient color comes fine for the datagrid column , but my requirement is when the user clicks on any other column the color for that column should change ..how do i do that …i have tried seting style on header release event of datagrid ..not working :( ..an suggestions….

  16. Sam says:

    Trying this on Flex 4.0. Getting the below error. Any suggestions?

    TypeError: Error #1009: Cannot access a property or method of a null object reference.
    at mx.skins.halo::DataGridHeaderBackgroundSkin/updateDisplayList()[E:\dev\4.0.0\frameworks\projects\framework\src\mx\skins\halo\DataGridHeaderBackgroundSkin.as:75]
    at com.edison.skins::DataGridHeaderBackgroundSkin/updateDisplayList()[C:\Sam\Adobe Flash Builder 4\TestDataGrid\src\com\edison\skins\DataGridHeaderBackgroundSkin.as:31]
    at mx.skins::ProgrammaticSkin/validateDisplayList()[E:\dev\4.0.0\frameworks\projects\framework\src\mx\skins\ProgrammaticSkin.as:503]
    at mx.managers::LayoutManager/validateClient()[E:\dev\4.0.0\frameworks\projects\framework\src\mx\managers\LayoutManager.as:932]
    at mx.core::UIComponent/validateNow()[E:\dev\4.0.0\frameworks\projects\framework\src\mx\core\UIComponent.as:7631]
    at mx.controls.dataGridClasses::DataGridBase/updateDisplayList()[E:\dev\4.0.0\frameworks\projects\framework\src\mx\controls\dataGridClasses\DataGridBase.as:594]
    at mx.controls::DataGrid/updateDisplayList()[E:\dev\4.0.0\frameworks\projects\framework\src\mx\controls\DataGrid.as:1741]
    at mx.controls.listClasses::ListBase/validateDisplayList()[E:\dev\4.0.0\frameworks\projects\framework\src\mx\controls\listClasses\ListBase.as:3962]
    at mx.managers::LayoutManager/validateDisplayList()[E:\dev\4.0.0\frameworks\projects\framework\src\mx\managers\LayoutManager.as:663]
    at mx.managers::LayoutManager/doPhasedInstantiation()[E:\dev\4.0.0\frameworks\projects\framework\src\mx\managers\LayoutManager.as:718]
    at mx.managers::LayoutManager/doPhasedInstantiationCallback()[E:\dev\4.0.0\frameworks\projects\framework\src\mx\managers\LayoutManager.as:1072]

Leave a Reply