Still struggling with this issue, and I'm quite confused about it having just re-read the ContextMenu reference documentation. The documentation states that:
In Flex, only top-level components in the application can have context menus. For example, if a DataGrid control is a child of a TabNavigator or VBox container, the DataGrid control cannot have its own context menu.
However, I don't see this principle being applied, since I have another component which has a tab navigator, with a tree component embedded in a vbox which is acting as one of the panes in the navigator:
I can quite happily attach context menus to the node in my tree in this case and it works just fine. The same is true in my problem with the advanced data grid problem mentioned above. I am rendering buttons in each of the cells in my grid, and these buttons all their own context menus (attached to their itemRenderers), which works just fine - it's only the tree column within the grid that I can't seem to get context menus working on the tree node.
Is anyone able to shed some light on this?
I'm also stuck on exactly the same issue. I'm not getting my custom context menus in advanced datagrid tree column.Could someone suggest me how to get this work?
I recently had to deal with the contextMenu madness... and so this may help...
You (GavinCroy) is right -- the documentation is wrong (at least as far as I understand it). And thank goodness. Because that would mean a single contextMenu for an entire view (each component) -- that would almost kill contextMenus ('cm' from here out). Each component has its own cm. And so whichever control has the focus, and the right click is performed, that component's cm is the one that is displayed. If a component does not have a cm assigned (its .contextMenu property = null), the parenting-component chain is checked, and the nearest ancestor with a cm assigned -- that is the cm that will be displayed.
But items in a List (DataGrid, Tree, etc.) are not components. So they don't have cm's. What you have to do is change the respective cm depending upon the item that is selected within each component -- basically emulating a 'state-change' for each component based upon it's selected item. This involves background code...
Something like this...
On Component ItemClick...
--> Depending on item-clicked, determine state (and thus appropriate cm for the component)...
--> set the component's cm for that 'state' (component.contextMenu = appropriateContextMenu)
--> so next right-click will produce appropriate cm (which may be essentially, the particular item's cm)
And that's basically it... and the appropriate cm may further depend upon the exact cell (row,col) with focus, not just the item (row).
As far as using the itemRenderer to store a contextMenu, I've never tried that, and I'm not sure if you were reporting that that actually works (ie right-clicking on an item/cell produces the itemRenderer's cm). My guess is that it doesn't work. If it does, it probably "shouldn't", as the renderer is "meant" to be used as graphic layouter/presenter/template, rather than as a "component" itself... But note that an ItemEditor component, such as a 'text-field' as a datagrid cell-editor, is an actual displayed component and so its context-menu will show up if it is active (shown/ in-use).
Another way of doing this, is to actually have some sort of ItemDataSet and ItemData objects (rather than, say, raw XML or a raw array), each of which may store a contextMenu itself..., and so on the item-click, the main component can have it's contextmenu set to the itemData instances cm... (eg: mainComp.contextMenu = itemData.contextMenu)
Hope that helps.
Thanks for the info! Glad to know I'm not going mad
Ok, I can see how to use a work around based on your suggestions. Ideally I would use a mouseover event (if one exists) to set up the menu before the user clicks. Users will not always click on an item before right clicking, so that's the only way I can think of to set up the context menu before that right click happens.
My other thought is to nest 'fake' components inside the tree, e.g. use a custom item renderer in the tree that uses a button with transparent skins placed over the item label, then see if a context menu on that component works as expected...
Thanks for giving me some direction!
Thanks to Gnomann for getting me thinking, I now have context menus working for my tree nodes in my advanced data grid. The approach I took was as follows:
1. Create a custom item renderer for the tree items in the grid
2. As each item has its data set, create the context menu for it
3. Attach a mouse over event listener to the node's label item (I'll also do the same for its icon object) which sets the context menu of the parent grid to this item's context menu
3. On mouse out remove the context menu from the parent grid (ultimately I'll probably need to restore some kind of default menu for the grid, I don't have the need for one at the moment.
My Item renderer code is attached
I have the same problem and I found your discussion here. What I am trying to do is following: In my main application I have a spark panel and inside that I have a tree. I have created custom context menu for each tree item. when I placed the tree inside the panel my custom menu is not working, when I remove the panel my costum menu is working. Is there a way to make work my custom tree inside a spark panel?
I also found that, the problem is only with spark panel component, the custom menu for tree works when I place it under mx panel component.