2010-05-19 7 views
0

J'ai un ItemRenderer qui est partagé par plusieurs applications (à l'intérieur d'un DataGrid), et j'aimerais y ajouter un menu contextuel (plutôt que dans chaque application). Le moteur de rendu est dérivé de la classe Canvas, et le code pour créer le menu contextuel ressemble à quelque chose comme:Flex 3: Possibilité d'ajouter un menu contextuel à un ItemRenderer dans un DataGrid?

  var menuItem:ContextMenuItem = new ContextMenuItem("Test"); 
      menuItem.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, contextCallback); 

      var customContextMenu:ContextMenu = new ContextMenu();    
      customContextMenu.hideBuiltInItems(); //hide flash menu 
      customContextMenu.customItems.push(menuItem);    
      this.contextMenu = customContextMenu; 

Cependant, lorsque je clique droit sur la cellule dans la grille de données, je reçois le menu Flash par défaut du contexte. Est-ce que ce n'est pas possible?

Edit: Voici un exemple entièrement runnable, qui ne montre pas le menu contextuel de:

Application.mxml:

<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" 
    layout="vertical" 
    verticalAlign="middle" 
    backgroundColor="white"> 

<mx:Model id="items"> 
    <items> 
     <item label="Item 1" data="i001" propertyA="Item 1.A" propertyB="Item 1.B" /> 
     <item label="Item 2" data="i002" propertyA="Item 2.A" propertyB="Item 2.B" /> 
     <item label="Item 3" data="i003" propertyA="Item 3.A" propertyB="Item 3.B" /> 
     <item label="Item 4" data="i004" propertyA="Item 4.A" propertyB="Item 4.B" /> 
     <item label="Item 5" data="i005" propertyA="Item 5.A" propertyB="Item 5.B" /> 
     <item label="Item 6" data="i006" propertyA="Item 6.A" propertyB="Item 6.B" /> 
     <item label="Item 7" data="i007" propertyA="Item 7.A" propertyB="Item 7.B" /> 
     <item label="Item 8" data="i008" propertyA="Item 8.A" propertyB="Item 8.B" /> 
    </items> 
</mx:Model> 

<mx:DataGrid id="dataGrid" width="400" dataProvider="{items.item}"> 
    <mx:columns> 
     <mx:DataGridColumn headerText="No Menu" dataField="label" /> 
     <mx:DataGridColumn headerText="Menu" dataField="propertyA" itemRenderer="canvasRenderer"/> 
    </mx:columns> 
</mx:DataGrid> 

canvasRenderer.mxml:

<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml" width="100%" verticalScrollPolicy="off" horizontalScrollPolicy="off" resize="this.setSize()" creationComplete="init()" implements="mx.controls.listClasses.IDropInListItemRenderer"> 
<mx:Script> 
    <![CDATA[ 
     import mx.controls.listClasses.ListData; 
     import mx.controls.dataGridClasses.DataGridListData; 
     import mx.controls.listClasses.BaseListData; 
     import mx.events.FlexEvent; 

     private var _listData:DataGridListData; 

     private function init():void { 
      var menuItem:ContextMenuItem = new ContextMenuItem("Copy", true); 
      menuItem.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, function():void { 
       trace("selected"); 
      }); 

      var menu:ContextMenu = new ContextMenu(); 
      menu.hideBuiltInItems(); //hide flash menu 
      menu.customItems.push(menuItem);  
      this.contextMenu = menu; 
     } 

     public override function set data(value:Object):void { 
      super.data = value; 
      if(_listData && myLabel) { 
       var text:String = _listData.label ? _listData.label : value[_listData.dataField]; 
       myLabel.text = text; 
       myLabel.toolTip = text; 
      } 
     } 

     public function get listData():BaseListData { return _listData; } 
     public function set listData(value:BaseListData):void { _listData = DataGridListData(value); } 
     public function setSize():void { myLabel.width = this.width; } 
    ]]> 
</mx:Script> 

<mx:Label id="myLabel" truncateToFit="true"/> 

Répondre

1

J'ai ajouté le menu contextuel à un itemRenderer dans une liste avec le Flextras DataSorter. Cependant, je ne vois aucune différence entre ce que j'ai fait et ce que vous faites.

code source ici: http://www.flextras.com/DataSorter/Samples/RightClick/srcview/index.html

et le fonctionnement Exemple http://www.flextras.com/DataSorter/Samples/RightClick/

Pouvez-vous partager plus de code? Quel est le "ceci" que vous ajoutez au menu contextuel? Votre temRenderer est-il en ligne ou un composant séparé?

+0

J'ai fourni un exemple runnable. Il semble que cela a quelque chose à voir avec le fait qu'il soit enveloppé dans la toile, mais c'est juste une supposition. – gmoniey

+0

Changez le texte de "Copier" à autre chose et votre code commence à fonctionner magiquement. "Copier" doit être un mot réservé ou quelque chose de similaire. – JeffryHouser

+0

Ahh ... très frustrant. Suppose que c'est ma faute. J'ai effectivement changé le texte dans mon premier échantillon, mais je n'ai jamais essayé d'exécuter ce code. Merci de votre attention. – gmoniey

2

Cela fonctionne:

<?xml version="1.0" encoding="utf-8"?> 
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" 
     layout="vertical" 
     verticalAlign="middle" 
     backgroundColor="white" 
     creationComplete="init()"> 

    <mx:Script> 
     <![CDATA[ 
      import mx.controls.Alert; 

      [Bindable] public var cm1:ContextMenu; 
      [Bindable] public var cm2:ContextMenu; 

      private function init():void { 
       var cmi1:ContextMenuItem = new ContextMenuItem("View item in column 1...", true); 
       cmi1.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, contextMenuItem_menuItemSelect); 

       cm1 = new ContextMenu(); 
       cm1.hideBuiltInItems(); 
       cm1.customItems = [cmi1]; 
       cm1.addEventListener(ContextMenuEvent.MENU_SELECT, contextMenu_menuSelect); 

       var cmi2:ContextMenuItem = new ContextMenuItem("View item in column 2...", true); 
       cmi2.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, contextMenuItem_menuItemSelect); 

       cm2 = new ContextMenu(); 
       cm2.hideBuiltInItems(); 
       cm2.customItems = [cmi2]; 
       cm2.addEventListener(ContextMenuEvent.MENU_SELECT, contextMenu_menuSelect); 
      } 

      private function contextMenu_menuSelect(evt:ContextMenuEvent):void { 
       dataGrid.selectedIndex = lastRollOverIndex; 
      } 

      private function contextMenuItem_menuItemSelect(evt:ContextMenuEvent):void { 
       var obj:Object = dataGrid.selectedItem; 
       Alert.show("Property A: " + obj.propertyA + "\n" + "Property B: " + obj.propertyB, obj.label, Alert.OK); 
      } 
     ]]> 
    </mx:Script> 

    <mx:Model id="items"> 
     <items> 
      <item label="Item 1" data="i001" propertyA="Item 1.A" propertyB="Item 1.B" /> 
      <item label="Item 2" data="i002" propertyA="Item 2.A" propertyB="Item 2.B" /> 
      <item label="Item 3" data="i003" propertyA="Item 3.A" propertyB="Item 3.B" /> 
      <item label="Item 4" data="i004" propertyA="Item 4.A" propertyB="Item 4.B" /> 
      <item label="Item 5" data="i005" propertyA="Item 5.A" propertyB="Item 5.B" /> 
      <item label="Item 6" data="i006" propertyA="Item 6.A" propertyB="Item 6.B" /> 
      <item label="Item 7" data="i007" propertyA="Item 7.A" propertyB="Item 7.B" /> 
      <item label="Item 8" data="i008" propertyA="Item 8.A" propertyB="Item 8.B" /> 
     </items> 
    </mx:Model> 

    <mx:Number id="lastRollOverIndex" /> 

    <mx:DataGrid id="dataGrid" width="400" dataProvider="{items.item}"> 
     <mx:columns> 
      <mx:DataGridColumn headerText="Label"> 
       <mx:itemRenderer> 
       <mx:Component> 
        <mx:Label text="{data.label}" contextMenu="{outerDocument.cm1}"/> 
       </mx:Component> 
       </mx:itemRenderer> 
      </mx:DataGridColumn> 

      <mx:DataGridColumn headerText="Property A"> 
       <mx:itemRenderer> 
       <mx:Component> 
        <mx:Label text="{data.propertyA}" contextMenu="{outerDocument.cm2}"/> 
       </mx:Component> 
       </mx:itemRenderer> 
      </mx:DataGridColumn> 
     </mx:columns> 
    </mx:DataGrid> 

    <mx:Label text="{dataGrid.selectedItem.label}" /> 

</mx:Application> 
+0

La question est pourquoi! Votre échantillon semble-t-il fonctionner avec un moteur de rendu en ligne? mais son échantillon ne semble pas fonctionner avec un moteur de rendu externe. Je ne pouvais pas faire fonctionner son échantillon non plus. – JeffryHouser

+0

J'ai compris! "Copier" n'apparaîtra pas. Ce doit être un mot réservé ou quelque chose de similaire. Changer le texte de son ContextMenuItem fait que les choses fonctionnent magiquement. – JeffryHouser

+0

Ahh. Oui. Flash Player n'autorise pas certains mots dans un menu contextuel personnalisé. Solution de contournement possible: http://www.themorphicgroup.com/blog/2009/07/06/contextmenu-copy-paste-delete/ –

Questions connexes