Question

How can I disable or hide ContextMenu customItems when a user right-clicks on a header? I tried to set customItems to an empty array:

class MyAdvancedDataGridHeaderRenderer
     extends AdvancedDataGridHeaderRenderer {
  protected function onComplete(event:FlexEvent) {
    contextMenu.customItems = [];
  }
}

...but the contextMenu for the header is null.

Was it helpful?

Solution

Figured it out. I just disabled the predetermined menu items when the header is moused-over. The ContextMenuItems are disabled if their caption exists in the hiddenContextItems Array.

I have provided an example that uses my ExtendedAdvancedDataGridHeaderRenderer object that I created in case anyone is interested.

The example below generates a chart with three columns: Red, Green, and Blue. The first row is the highest contrast for that color and every row after that contrast level is decreased. This produces a gradient effect on the grid. You can copy the hex value of the color to your clipboard by right-clicking on the cell.

ExtendedAdvancedDataGridHeaderRenderer.as

package components {
  import flash.events.MouseEvent;
  import flash.ui.ContextMenuItem;

  import mx.controls.AdvancedDataGrid;
  import mx.controls.advancedDataGridClasses.AdvancedDataGridHeaderRenderer;

  public class ExtendedAdvancedDataGridHeaderRenderer extends AdvancedDataGridHeaderRenderer {

    private var _hiddenContextMenuItems:Array; // of String

    public function get hiddenContextMenuItems():Array {
      return _hiddenContextMenuItems;
    }

    public function set hiddenContextMenuItems(value:Array):void {
      _hiddenContextMenuItems = value;
    }

    public function ExtendedAdvancedDataGridHeaderRenderer() {
      super();
      hiddenContextMenuItems = [ExtendedAdvancedDataGrid.MENU_COPY];
      this.addEventListener(MouseEvent.MOUSE_OVER, onRollOver);
      this.addEventListener(MouseEvent.MOUSE_OUT, onRollOut);
    }

    protected function onRollOver(event:MouseEvent):void {
      disableMenuItems(hiddenContextMenuItems);
    }

    protected function onRollOut(event:MouseEvent):void {
      disableMenuItems([]);
    }

    private function disableMenuItems(arr:Array):void {
      if (arr != null && this.owner is AdvancedDataGrid) {
        var adg:AdvancedDataGrid = this.owner as AdvancedDataGrid;
        if (adg.contextMenu != null && adg.contextMenu.customItems != null) {
          for each (var item:ContextMenuItem in adg.contextMenu.customItems) {
            item.enabled = !arrContainsStr(arr, item.caption);
          }
        }
      }
    }

    private function arrContainsStr(arr:Array, str:String):Boolean {
      for each (var arrStr:String in arr)
        if (arrStr == str)
          return true;
      return false;
    }
  }
}

ExtendedAdvancedDataGridItemRenderer.as

package components {
  import mx.controls.advancedDataGridClasses.AdvancedDataGridItemRenderer;

  public class ExtendedAdvancedDataGridItemRenderer
      extends AdvancedDataGridItemRenderer {
    public function ExtendedAdvancedDataGridItemRenderer() {
      super();
    }

    override public function set data(value:Object):void {
      super.data = value;
      this.background = true;
      var bgColor:uint = parseInt(listData.label, 16);
      var fgColor:uint = bgColor ^ 0xFFFFFF;
      this.backgroundColor = bgColor;
      this.setStyle('color', fgColor);
      this.setStyle('textRollOverColor', 0xFFFFFF);
    }
  }
}

ExtendedAdvancedDataGridColumn.as

package components {
  import mx.controls.advancedDataGridClasses.AdvancedDataGridColumn;
  import mx.core.ClassFactory;

  public class ExtendedAdvancedDataGridColumn extends AdvancedDataGridColumn {
    public function ExtendedAdvancedDataGridColumn(columnName:String=null) {
      super(columnName);
      headerRenderer = new ClassFactory(ExtendedAdvancedDataGridHeaderRenderer);
      itemRenderer = new ClassFactory(ExtendedAdvancedDataGridItemRenderer);
    }
  }
}

ExtendedAdvancedDataGrid.as

package components {
  import flash.display.Sprite;
  import flash.events.ContextMenuEvent;
  import flash.system.System;
  import flash.ui.ContextMenu;
  import flash.ui.ContextMenuItem;

  import mx.controls.AdvancedDataGrid;
  import mx.controls.advancedDataGridClasses.AdvancedDataGridItemRenderer;
  import mx.events.FlexEvent;
  import mx.utils.StringUtil;

  public class ExtendedAdvancedDataGrid extends AdvancedDataGrid {

    public static const MENU_COPY:String = 'Copy Hex Value';

    public function ExtendedAdvancedDataGrid() {
      super();
      this.addEventListener(FlexEvent.INITIALIZE, onInitialize);
    }

    protected function onInitialize(event:FlexEvent):void {
      contextMenu = new ContextMenu();
      contextMenu.hideBuiltInItems();
      var item:ContextMenuItem = new ContextMenuItem(MENU_COPY);
      item.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, copyCellContents);
      contextMenu.customItems.push(item);
    }

    protected function copyCellContents(event:ContextMenuEvent):void {
      if (event.mouseTarget is AdvancedDataGridItemRenderer) {
        var text:String = (event.mouseTarget as AdvancedDataGridItemRenderer).text;
        System.setClipboard(StringUtil.substitute('#{0}', text));
      }
    }
  }
}

App.mxml

<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
               xmlns:s="library://ns.adobe.com/flex/spark" 
               xmlns:mx="library://ns.adobe.com/flex/mx"
               minWidth="955" minHeight="600"
               xmlns:components="components.*"
               initialize="onInitialize(event)">
  <fx:Script>
    <![CDATA[
      import mx.collections.ArrayCollection;
      import mx.events.FlexEvent;
      import mx.utils.StringUtil;

      [Bindable] protected var gridData:ArrayCollection;

      protected function onInitialize(event:FlexEvent):void {
        gridData = new ArrayCollection();
        for (var i:uint = 15; i >= 0; i--) {
          var hexVal:String = intVal.toString(i)
          var red:String = StringUtil.substitute('{0}{0}0000', hexVal); 
          var green:String = StringUtil.substitute('00{0}{0}00', hexVal); 
          var blue:String = StringUtil.substitute('0000{0}{0}', hexVal); 
          gridData.addItem({'red': red, 'green': green, 'blue': blue});
        }
        grid.invalidateDisplayList();
      }
    ]]>
  </fx:Script>
  <s:BorderContainer horizontalCenter="0">
    <components:ExtendedAdvancedDataGrid id="grid" dataProvider="{gridData}"
      rowCount="{gridData.length + 1}">
    <components:columns>
      <components:ExtendedAdvancedDataGridColumn dataField="red" headerText="Red"/>
      <components:ExtendedAdvancedDataGridColumn dataField="green" headerText="Green"/>
      <components:ExtendedAdvancedDataGridColumn dataField="blue" headerText="Blue"/>
    </components:columns>
  </components:ExtendedAdvancedDataGrid>
  </s:BorderContainer>
</s:Application>
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top