7 Replies Latest reply on Jul 30, 2010 12:26 AM by Groovee2010

    Skinning selected DataGrid header in Flex 4

    Groovee2010

      Hi,

       

      What I'm trying to do seems trivial, but after hours of searching for historical clues I have still not achieved it. I simply want to reskin only the selected header. There seems to be multiple approaches:

       

      1) define a custom headerRenderer - but this ends up with the sort indicator cobbled on top of your custom drawn area

      2) rework the header background skin to clip/draw the selected column differently - but this requires clipping to the selected column, and figuring out the dimensions to clip to

       

      Am I missing an obvious and easier solution?  Any examples out there?

       

      Thanks!

        • 1. Re: Skinning selected DataGrid header in Flex 4
          Flex harUI Adobe Employee

          When you say "selected" header, are you talking about the one that is now

          the sort column or the one selected during dragging or something else?

          • 2. Re: Skinning selected DataGrid header in Flex 4
            Groovee2010 Level 1

            Hi Alex,

             

            Sorry for the ambiguity. I wish to indentify the current sort column with a colored header in addition to the sort indicator.

             

            Thanks for any assistance.

            • 3. Re: Skinning selected DataGrid header in Flex 4
              Groovee2010 Level 1

              So Alex, any hints on how to do that?

               

              Thanks!

              • 4. Re: Skinning selected DataGrid header in Flex 4
                Flex harUI Adobe Employee

                I would make a custom header renderer.  It can check the

                owner.dataProvider.sort to see if it should have different visuals.

                1 person found this helpful
                • 5. Re: Skinning selected DataGrid header in Flex 4
                  Groovee2010 Level 1

                  Thanks. One last question here, I hope.

                   

                  When I draw a gradient within my custom HeaderBackGroundSkin for the entire width of the grid, the default sort indicators properly sit on top of it.

                   

                  But when I specify a custom Header for each column, it is only given the width not used by the sort indicator (when present), so my highlighted gradient does not fill the entire column header.

                   

                  Is the solution to similarly skin the sort arrow? It seems that this should be easier (especially since it's not even really Flex 4 is it?). But mostly I was surprised to not find an example of somebody already doing it since it seems like such a common desire.

                   

                  Thanks again.

                  • 6. Re: Skinning selected DataGrid header in Flex 4
                    Flex harUI Adobe Employee

                    Folks have done this before.  The reason it is hard is because DG is not a

                    Spark component so skinning is unpredictable.

                     

                    I'm pretty sure they way folks do it is by drawing not within your given

                    size but based on the column's width.  You can draw outside your bounds and

                    it won't get clipped.  The column is the header renderer's data object.

                    1 person found this helpful
                    • 7. Re: Skinning selected DataGrid header in Flex 4
                      Groovee2010 Level 1

                      Thanks again Alex.

                       

                      I managed to achieve something satisfactory with the following custom HeaderRenderer. The negative padding on the right side allows the gradient to extend underneath the sort skin to fill the entire column. This seemed easier (if not cleaner) than also skinning the sort arrow skin in the same way.

                       

                      I also had to extend DataGridHeader and override drawHeaderIndicator (for the rollover of the column header) and drawSelectionIndicator (for the transitionary state of clicking on the column header before the sort takes effect).

                       

                      Still a work in progress, but hopefully this will save the next Googler some time in achieving any of these goals.  And of course I welcome any refinements or any admonishments that I'm doing something really stupid.

                       

                      <?xml version="1.0" encoding="utf-8"?>

                      <s:Group>

                       

                       

                      implements="mx.controls.listClasses.IListItemRenderer"

                      xmlns:fx="

                      http://ns.adobe.com/mxml/2009"

                      xmlns:s="

                      library://ns.adobe.com/flex/spark"

                      xmlns:mx="

                      library://ns.adobe.com/flex/halo"

                      width="

                      100%" height="100%">

                       

                       

                       

                      <fx:Script>

                      <![CDATA[

                       

                       

                      import com.company.player.model.Constants;

                       

                       

                      import mx.collections.ArrayCollection;

                       

                      import mx.controls.DataGrid;

                       

                      import mx.controls.dataGridClasses.DataGridColumn;

                       

                      import mx.controls.listClasses.IListItemRenderer;

                       

                      import mx.controls.listClasses.ListBase;

                       

                       

                      private var _data:Object;

                       

                       

                      static private const LABEL_BUFFER:int = 4;

                       

                      static private const SORT_INDICATOR_WIDTH:int = 14;

                       

                       

                       

                       

                       

                      override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void

                      {

                       

                       

                      var owner:DataGrid = owner as DataGrid;

                       

                       

                      var col:DataGridColumn = data as DataGridColumn;

                       

                       

                      var bSorted:Boolean = false;

                       

                       

                      var ac:ArrayCollection = owner.dataProvider as ArrayCollection;

                       

                      if (ac && ac.sort)

                      {

                       

                      // there's a sort in place - is it on this column?

                       

                       

                      var sortFieldName:String = ac.sort.fields[0].name;

                       

                      bSorted = (sortFieldName == col.dataField);

                      }

                       

                      gradientOverlay.alpha = bSorted ? 1 : 0;

                       

                      gradientOverlay.visible = bSorted;

                       

                      lbl.width = col.width - LABEL_BUFFER - (bSorted ? SORT_INDICATOR_WIDTH : 0);

                      lbl.text = col.headerText;

                      lbl.setStyle(

                      "color", bSorted ? "#343434" : "#767676");

                       

                       

                      super.updateDisplayList(unscaledWidth, unscaledHeight);

                      }

                       

                      ]]>

                       

                      </fx:Script>

                       

                       

                       

                       

                      <s:HGroup id="gradientOverlay" width="100%" height="100%" paddingTop="-2" paddingRight="{-SORT_INDICATOR_WIDTH}" >

                       

                       

                      <s:Rect width="100%" height="100%" >

                       

                       

                      <s:fill>

                       

                       

                      <s:LinearGradient rotation="90">

                       

                       

                      <s:GradientEntry color="{Constants.SELECTION_GRADIENT1}" alpha="1"/>

                       

                       

                      <s:GradientEntry color="{Constants.SELECTION_GRADIENT2}" alpha="1"/>

                       

                       

                      </s:LinearGradient>

                       

                      </s:fill>

                       

                       

                      </s:Rect>

                       

                      </s:HGroup>

                       

                       

                       

                      <s:HGroup width="100%" height="100%" verticalAlign="middle" paddingLeft="{LABEL_BUFFER}" >

                       

                       

                      <s:Label id="lbl" maxDisplayedLines="1" showTruncationTip="true" />

                       

                      </s:HGroup>

                       

                        

                        

                        

                      </s:Group>