开发者

Flex 3: Possible to add a Context Menu to a ItemRenderer inside a DataGrid?

I have an ItemRenderer that is shared by several applications (inside a DataGrid), and I would like to add a context menu to it (rather than in each application). The renderer is derived from the Canvas class, and the code to create the context menu looks something like:

            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;

However, when I right click on the cell in the datagrid, I get the default Flash Context Menu. Is this not possible?

Edit: Here is a fully runnable example, which doesn't show the context menu's:

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%" verticalScrollPolic开发者_开发百科y="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"/>


This works:

<?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>


I've added the context menu to an itemRenderer in a List with the Flextras DataSorter. However, I don't see any difference between what I did and what you're doing.

Source code here: http://www.flextras.com/DataSorter/Samples/RightClick/srcview/index.html

and the running Sample http://www.flextras.com/DataSorter/Samples/RightClick/

Can you share more code? What is the "this" that you're adding the context menu too? Is your temRenderer in-line or a separate component?

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜