1.21 gigawatts
1.21 gigawatts

Reputation: 17736

How to set the header styles of a Spark DataGrid

How do I update the look of the header parts in a Spark DataGrid? This is a how to community wiki post to set the header background color, header text color, column separator and sort arrow indicator symbol color of a Spark DataGrid.

Upvotes: 2

Views: 6230

Answers (1)

1.21 gigawatts
1.21 gigawatts

Reputation: 17736

I found a few examples online about how to style the Spark DataGrid header but not in the way I've described. So here is how I did it.

MXML:

<s:DataGrid />

CSS:

    s|DataGrid {
        symbolColor:#FF0000; /* defines the sort indicator color */
    }

    s|GridItemRenderer {
        color:#0000FF;       /* defines the header text color */
        chromeColor:#00FF00; /* defines the header background color */
    }

That's it. Well, not quite. The GridItemRenderer uses gradients. If you do not want those you have to do some extra work in addition to the above.

PART II
To remove the gradients we have to create two new skin classes. A new data grid skin based on spark.skins.spark.DataGridSkin and new data grid header skin based on spark.skins.spark.DefaultGridHeaderRenderer. The first skin extends DataGridSkin. The second skin is a copy of DefaultGridHeaderRenderer.

MXML:

<s:DataGrid skinClass="view.skins.AbstractDataGridSkin"/>

AbstractDataGridSkin:

<?xml version="1.0" encoding="utf-8"?>
<spark:DataGridSkin 
    xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:s="library://ns.adobe.com/flex/spark" 
    xmlns:mx="library://ns.adobe.com/flex/mx"
    xmlns:fb="http://ns.adobe.com/flashbuilder/2009"
    xmlns:spark="spark.skins.spark.*" 
    xmlns:skins="view.skins.*"
    >

    <fx:Declarations>
        <fx:Component id="headerRenderer">
            <skins:AbstractDataGridHeaderSkin />
        </fx:Component>


    <!--- Change the look of the column separator  -->
    <fx:Component id="columnSeparator">
        <s:Line>
            <s:stroke>
                <s:SolidColorStroke color="0xA6A6A6" weight="1" caps="square"/>
            </s:stroke>
        </s:Line>
    </fx:Component>

    <!--- Defines the look of the header column separator -->
    <fx:Component id="headerColumnSeparator">
        <s:Line>
            <s:stroke>
                <s:SolidColorStroke color="0x00FF00" weight="1" caps="square" />
            </s:stroke>
        </s:Line>
    </fx:Component>
    </fx:Declarations>
</spark:DataGridSkin>

This class points to the new DataGridHeaderSkin.

AbstractDataGridHeaderSkin:

There is a lot of code in the DefaultGridHeaderRenderer that I don't want to paste into this example so I'm only going to show what's changed.

First remove all the Rect layers except "layer 2 fill". Next, update "layer 2 fill" to a solid color fill as shown below:

<s:GridItemRenderer minWidth="21" minHeight="21"
                xmlns:fx="http://ns.adobe.com/mxml/2009" 
                xmlns:s="library://ns.adobe.com/flex/spark" 
                xmlns:mx="library://ns.adobe.com/flex/mx">

<!-- ...original code here.. -->

<!-- layer 2: fill -->
<!--- @private -->
<!---  Set left and right to -1 to fill out header width 
<s:Rect id="fill" left="0" right="0" top="0" bottom="-1"> -->
<s:Rect id="fill" left="-1" right="-1" top="0" bottom="0">
    <s:fill>
        <s:SolidColor color="0xFFFFFF" color.hovered="0xBBBDBD" color.down="0xAAAAAA" alpha="1" >   
        </s:SolidColor>
    </s:fill>
</s:Rect>

<!-- ...original code here.. -->

</s:GridItemRenderer>

We also have to update the sortIndicatorArrow to remove gradients from there.

<fx:Component id="defaultSortIndicator">
    <s:Path data="M 3.5 7.0 L 0.0 0.0 L 7.0 0.0 L 3.5 7.0" implements="spark.components.gridClasses.IGridVisualElement">
        <fx:Script>
            <![CDATA[
                import spark.components.DataGrid;
                import spark.components.Grid;

                /**
                 *  @private
                 */
                public function prepareGridVisualElement(grid:Grid, rowIndex:int, columnIndex:int):void
                {
                    const dataGrid:DataGrid = grid.dataGrid;
                    if (!dataGrid)
                        return;

                    const color:uint = dataGrid.getStyle("symbolColor");
                    arrowFill.color = color;
                }
            ]]>
        </fx:Script>

        <s:fill>
            <s:SolidColor id="arrowFill" color="0" />
        </s:fill>
    </s:Path>
</fx:Component>

That's it.

NOTE: If you are using the chrome color it transforms the header fill background. You can add the fill to the exclusions (update the updateDisplayList method) or you can set the fill alpha values like this.

<!-- layer 2: fill -->
<!--- @private -->
<!---  Set left and right to -1 to fill out header width 
<s:Rect id="fill" left="0" right="0" top="0" bottom="-1"> -->
<s:Rect id="fill" left="-1" right="-1" top="0" bottom="0">
    <s:fill>
        <s:SolidColor alpha="1" 
                      alpha.hovered=".95"
                      alpha.down="1"/>
    </s:fill>
</s:Rect>

or add this to updateDisplayList and set the colors on the fill (chromeColor would not need to be set then)
var exclusions:Array = [fill, labelDisplay, sortIndicatorInstance];

At some point these common styles will hopefully be available on the Spark DataGrid. Spark made it more flexible to define the look and feel of a component which is good but then hardcoded style values into the default skin classes that come with the Flex SDK. It's now left up to the developer to find and modify these which is not always easy to do.

To remove the vertical column lines or any other non-required skin part set the property of the part to null in the initialize event like so:

AbstractDataGridSkin:

<?xml version="1.0" encoding="utf-8"?>
<spark:DataGridSkin 
    xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:s="library://ns.adobe.com/flex/spark" 
    xmlns:mx="library://ns.adobe.com/flex/mx"
    xmlns:fb="http://ns.adobe.com/flashbuilder/2009"
    xmlns:spark="spark.skins.spark.*" 
    xmlns:skins="view.skins.*"
    initialize="caretIndicator = null;columnSeparator=null"
    />

To set the height of the header set it on the headerComponent property:

    <fx:Component id="headerRenderer">
        <skins:AbstractDataGridHeaderSkin height="36" />
    </fx:Component>

Sources: http://ramblingdeveloper.com/ramblings/2011/9/25/skinning-a-flex-spark-datagrid-header.html

Upvotes: 4

Related Questions