How can you display a multi-row column header using the Flex Spark Data Grid?

How can you display a multi-row column header using the Flex Spark Data Grid for Flex 4.5?

+4
source share
6 answers

To extend Constantiner's answer, you need to create a custom HeaderRenderer and set Label maxDisplayedLines to 2. Here is the sample renderer that I found :

Myrenderer.mxml

 <?xml version="1.0" encoding="utf-8"?> <!-- ADOBE SYSTEMS INCORPORATED Copyright 2010 Adobe Systems Incorporated All Rights Reserved. NOTICE: Adobe permits you to use, modify, and distribute this file in accordance with the terms of the license agreement accompanying it. --> <!--- The DefaultGridHeaderRenderer class defines the default header renderer for the columns of a Spark DataGrid control. <p>Subclasses defined in MXML can redefine the values of the <code>labelDisplay</code> and <code>sortIndicator</code> properties.</p> @see spark.components.DataGrid @see spark.components.GridColumnHeaderGroup @see spark.components.gridClasses.GridItemRenderer @langversion 3.0 @playerversion Flash 10 @playerversion AIR 2.0 @productversion Flex 4.5 --> <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"> <fx:Declarations> <!--- The default value of the <code>sortIndicator</code> property. It must be an IFactory for an IVisualElement. <p>This value is specified in a <code>fx:Declaration</code> block and can be overridden by a declaration with <code>id="defaultSortIndicator"</code> in an MXML subclass.</p> @langversion 3.0 @playerversion Flash 10 @playerversion AIR 2.0 @productversion Flex 4.5 --> <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"); arrowFill1.color = color; arrowFill2.color = color; } ]]> </fx:Script> <s:fill> <s:RadialGradient rotation="90" focalPointRatio="1"> <!--- @private --> <s:GradientEntry id="arrowFill1" color="0" alpha="0.6" /> <!--- @private --> <s:GradientEntry id="arrowFill2" color="0" alpha="0.8" /> </s:RadialGradient> </s:fill> </s:Path> </fx:Component> <!--- Displays the renderer label property, which is set to the column <code>headerText</code>. It must be an instance of a <code>TextBase</code>, like <code>s:Label</code>. <p>This visual element is added to the <code>labelDisplayGroup</code> by the renderer's <code>prepare()</code> method. Any size/location constraints specified by the labelDisplay define its location relative to the labelDisplayGroup.</p> <p>This value is specified with a <code>fx:Declaration</code> and can be overridden by a declaration with <code>id="labelDisplay"</code> in an MXML subclass.</p> @langversion 3.0 @playerversion Flash 10 @playerversion AIR 2.0 @productversion Flex 4.5 --> <s:Label id="labelDisplay" verticalCenter="1" left="0" right="0" top="0" bottom="0" textAlign="start" fontWeight="bold" verticalAlign="middle" maxDisplayedLines="2" showTruncationTip="true" /> </fx:Declarations> <fx:Script> <![CDATA[ import spark.components.gridClasses.IGridVisualElement; import mx.core.IVisualElement; import spark.components.DataGrid; import spark.components.GridColumnHeaderGroup; import spark.components.gridClasses.GridColumn; /** * @private */ private function dispatchChangeEvent(type:String):void { if (hasEventListener(type)) dispatchEvent(new Event(type)); } //---------------------------------- // maxDisplayedLines //---------------------------------- private var _maxDisplayedLines:int = 1; [Bindable("maxDisplayedLinesChanged")] [Inspectable(minValue="-1")] /** * The value of this property is used to initialize the * <code>maxDisplayedLines</code> property of this renderer * <code>labelDisplay</code> element. * * @copy spark.components.supportClasses.TextBase#maxDisplayedLines * * @default 1 * * @langversion 3.0 * @playerversion Flash 10 * @playerversion AIR 1.5 * @productversion Flex 4.5 */ public function get maxDisplayedLines():int { return _maxDisplayedLines; } /** * @private */ public function set maxDisplayedLines(value:int):void { if (value == _maxDisplayedLines) return; _maxDisplayedLines = value; if (labelDisplay) labelDisplay.maxDisplayedLines = value; invalidateSize(); invalidateDisplayList(); dispatchChangeEvent("maxDisplayedLinesChanged"); } //---------------------------------- // sortIndicator //---------------------------------- private var _sortIndicator:IFactory; private var sortIndicatorInstance:IVisualElement; [Bindable("sortIndicatorChanged")] /** * A visual element that displayed when the column is sorted. * * <p>The sortIndicator visual element is added to the <code>sortIndicatorGroup</code> * by this renderer <code>prepare()</code> method. Any size/location constraints * specified by the sortIndicator define its location relative to the sortIndicatorGroup.</p> * * @default null * * @langversion 3.0 * @playerversion Flash 10 * @playerversion AIR 1.5 * @productversion Flex 4.5 */ public function get sortIndicator():IFactory { return (_sortIndicator) ? _sortIndicator : defaultSortIndicator; } /** * @private */ public function set sortIndicator(value:IFactory):void { if (_sortIndicator == value) return; _sortIndicator = value; if (sortIndicatorInstance) { sortIndicatorGroup.includeInLayout = false; sortIndicatorGroup.removeElement(sortIndicatorInstance); sortIndicatorInstance = null; } invalidateDisplayList(); dispatchChangeEvent("sortIndicatorChanged"); } /** * @private * Create and add the sortIndicator to the sortIndicatorGroup and the * labelDisplay into the labelDisplayGroup. */ override public function prepare(hasBeenRecycled:Boolean):void { super.prepare(hasBeenRecycled); if (labelDisplay && labelDisplayGroup && (labelDisplay.parent != labelDisplayGroup)) { labelDisplayGroup.removeAllElements(); labelDisplayGroup.addElement(labelDisplay); } const column:GridColumn = this.column; if (sortIndicator && column && column.grid && column.grid.dataGrid && column.grid.dataGrid.columnHeaderGroup) { const dataGrid:DataGrid = column.grid.dataGrid; const columnHeaderGroup:GridColumnHeaderGroup = dataGrid.columnHeaderGroup; if (columnHeaderGroup.isSortIndicatorVisible(column.columnIndex)) { if (!sortIndicatorInstance) { sortIndicatorInstance = sortIndicator.newInstance(); sortIndicatorGroup.addElement(sortIndicatorInstance); } // Initialize sortIndicator sortIndicatorInstance.visible = true; const gridVisualElement:IGridVisualElement = sortIndicatorInstance as IGridVisualElement; if (gridVisualElement) gridVisualElement.prepareGridVisualElement(column.grid, -1, column.columnIndex); sortIndicatorGroup.includeInLayout = true; sortIndicatorGroup.scaleY = (column.sortDescending) ? 1 : -1; } else { if (sortIndicatorInstance) { sortIndicatorGroup.removeElement(sortIndicatorInstance); sortIndicatorGroup.includeInLayout = false; sortIndicatorInstance = null; } } } } ]]> </fx:Script> <s:states> <s:State name="normal" /> <s:State name="hovered" /> <s:State name="down" /> </s:states> <!-- layer 1: shadow --> <!--- @private --> <s:Rect id="shadow" left="-1" right="-1" top="-1" bottom="-1" radiusX="2"> <s:fill> <s:LinearGradient rotation="90"> <s:GradientEntry color="0x000000" color.down="0xFFFFFF" alpha="0.01" alpha.down="0" /> <s:GradientEntry color="0x000000" color.down="0xFFFFFF" alpha="0.07" alpha.down="0.5" /> </s:LinearGradient> </s:fill> </s:Rect> <!-- layer 2: fill --> <!--- @private --> <s:Rect id="fill" left="0" right="0" top="0" bottom="0"> <s:fill> <s:LinearGradient rotation="90"> <s:GradientEntry color="0xFFFFFF" color.hovered="0xBBBDBD" color.down="0xAAAAAA" alpha="0.85" /> <s:GradientEntry color="0xD8D8D8" color.hovered="0x9FA0A1" color.down="0x929496" alpha="0.85" /> </s:LinearGradient> </s:fill> </s:Rect> <!-- layer 3: fill lowlight --> <!--- @private --> <s:Rect id="lowlight" left="0" right="0" top="0" bottom="0"> <s:fill> <s:LinearGradient rotation="270"> <s:GradientEntry color="0x000000" ratio="0.0" alpha="0.0627" /> <s:GradientEntry color="0x000000" ratio="0.48" alpha="0.0099" /> <s:GradientEntry color="0x000000" ratio="0.48001" alpha="0" /> </s:LinearGradient> </s:fill> </s:Rect> <!-- layer 4: fill highlight --> <!--- @private --> <s:Rect id="highlight" left="0" right="0" top="0" bottom="0"> <s:fill> <s:LinearGradient rotation="90"> <s:GradientEntry color="0xFFFFFF" ratio="0.0" alpha="0.33" alpha.hovered="0.22" alpha.down="0.12"/> <s:GradientEntry color="0xFFFFFF" ratio="0.48" alpha="0.33" alpha.hovered="0.22" alpha.down="0.12" /> <s:GradientEntry color="0xFFFFFF" ratio="0.48001" alpha="0" /> </s:LinearGradient> </s:fill> </s:Rect> <!-- layer 5: highlight stroke (all states except down) --> <!--- @private --> <s:Rect id="highlightStroke" left="0" right="0" top="0" bottom="0" excludeFrom="down"> <s:stroke> <s:LinearGradientStroke rotation="90" weight="1"> <s:GradientEntry color="0xFFFFFF" alpha.hovered="0.22" /> <s:GradientEntry color="0xD8D8D8" alpha.hovered="0.22" /> </s:LinearGradientStroke> </s:stroke> </s:Rect> <!-- layer 6: highlight stroke (down state only) --> <!--- @private --> <s:Rect id="hldownstroke1" left="0" right="0" top="0" bottom="0" includeIn="down"> <s:stroke> <s:LinearGradientStroke rotation="90" weight="1"> <s:GradientEntry color="0x000000" alpha="0.25" ratio="0.0" /> <s:GradientEntry color="0x000000" alpha="0.25" ratio="0.001" /> <s:GradientEntry color="0x000000" alpha="0.07" ratio="0.0011" /> <s:GradientEntry color="0x000000" alpha="0.07" ratio="0.965" /> <s:GradientEntry color="0x000000" alpha="0.00" ratio="0.9651" /> </s:LinearGradientStroke> </s:stroke> </s:Rect> <!--- @private --> <s:Rect id="hldownstroke2" left="1" right="1" top="1" bottom="1" includeIn="down"> <s:stroke> <s:LinearGradientStroke rotation="90" weight="1"> <s:GradientEntry color="0x000000" alpha="0.09" ratio="0.0" /> <s:GradientEntry color="0x000000" alpha="0.00" ratio="0.0001" /> </s:LinearGradientStroke> </s:stroke> </s:Rect> <s:HGroup left="7" right="7" top="5" bottom="5" gap="8" verticalAlign="middle"> <s:BitmapImage source="54.gif" /> <!-- layer 7: Container for labelDisplay:TextBase --> <!--- Defines the size and location of the labelDisplay visual element. <p>The <code>labelDisplay</code> is added to this Group by the renderer <code>prepare()</code> method. Any size/location constraints specified by the labelDisplay define its layout relative to the labelDisplayGroup.</p> @langversion 3.0 @playerversion Flash 10 @playerversion AIR 2.0 @productversion Flex 4.5 --> <s:Group id="labelDisplayGroup" width="100%" /> <!-- layer 8: Container for sortIndicator:IVisualElement --> <!--- Defines the size and location of the sortIndicator visual element. <p>The <code>sortIndicator</code> is added to this Group by the renderer <code>prepare()</code> method. Any size/location constraints specified by the sortIndicator define its layout relative to the sortIndicatorGroup. This Group is only included in the layout when the sortIndicator is visible.</p> @langversion 3.0 @playerversion Flash 10 @playerversion AIR 2.0 @productversion Flex 4.5 --> <s:Group id="sortIndicatorGroup" includeInLayout="false" /> </s:HGroup> </s:GridItemRenderer> 

And then, to use it in your DataGrid, just follow the Constantiner example:

 <s:DataGrid> <s:columns> <s:ArrayList> <s:GridColumn headerRenderer="MyRenderer" /> </s:ArrayList> </s:columns> </s:DataGrid> 
+3
source

Try using a custom headerRenderer as follows:

 <s:DataGrid> <s:columns> <s:ArrayList> <s:GridColumn headerRenderer="MyRenderer" /> </s:ArrayList> </s:columns> </s:DataGrid> 

A sample rendering with a single-line header {flex4.5 SDK root}/frameworks/projects/spark/src/spark/skins/spark/DefaultGridHeaderRenderer.mxml can be created {flex4.5 SDK root}/frameworks/projects/spark/src/spark/skins/spark/DefaultGridHeaderRenderer.mxml .

+1
source

I do not see the headerRenderer property of the headerRenderer property in sdk, which I use, so I could not accept other answers. Here is my solution:

MultiLineColumnHeaderRenderer.mxml:

 <?xml version="1.0" encoding="utf-8"?> <s:ItemRenderer xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" autoDrawBackground="true"> <fx:Script> <![CDATA[ import spark.components.supportClasses.GridColumn; ]]> </fx:Script> <s:TextArea editable="false" text="{(data as GridColumn).headerText}" /> </s:ItemRenderer> 

The init function in a view using datagrid:

  public function init():void{ dataGrid.columnHeaderBar.firstItemRenderer = new ClassFactory(MultiLineColumnHeaderRenderer); dataGrid.columnHeaderBar.itemRenderer = new ClassFactory(MultiLineColumnHeaderRenderer); } 

And using &#13; in headerText for GridColumn:

 <s:GridColumn headerText="Line1&#13;Line2&#13;Line2"/> 
+1
source

Make a copy of the DataGridSkin and place it in the source code. Then edit line 154 for this -

 <fx:Component id="headerRenderer"> <s:DefaultGridHeaderRenderer maxDisplayedLines="2"/> </fx:Component> 

Hope this helps,

Rich

+1
source

You have to do this: -Create your own SparkDatagrid skin by creating a default copy -Create a custom DataGrid HeaderRenderer -Just create a new GridItemRenderer (A) and put the default DataGridHeaderRenderer code in a new GridItemRenderer (A) -Wrap in the label "ADisplay and label" change its property "maxDisplayedLines" from 1 to 2 - But go back to your usual Spark Satagrid Skin and find the component "headerRenderer". - Install it with an instance of your custom GridItemRender (A)

It worked for me ... hope it does the same for you

MARCO

0
source

Or

if you do not want to create a new Renderer for only 1 property, you can simply configure the property as follows:

 ... <s:GridColumn width="100" dataField="myDataField" headerText="myHeaderText"> <s:headerRenderer> <fx:Component> <s:DefaultGridHeaderRenderer maxDisplayedLines="2" /> </fx:Component> </s:headerRenderer> </s:GridColumn> ... 

if you look at the code inside the DefaultGridHeaderRenderer component, you will see that when you install it, it will change the value in the labelDisplay method

But, if you have many columns, and it can be boring to put the same code for a lot of time, just create a new component that extends the Datagrid spark (or nests depending on your need), then the code:

 public function set columns(value:IList):void { for each (var gridColumn:GridColumn in value.toArray()) { var headerRenderer:ClassFactory = new ClassFactory(DefaultGridHeaderRenderer); headerRenderer.properties = {maxDisplayedLines: 2}; gridColumn.headerRenderer = headerRenderer; } _columns = value; } [Bindable] public function get columns():IList { return _columns; } 
0
source

Source: https://habr.com/ru/post/1347980/


All Articles