2009-11-24 116 views
1

我的任務是在DataGrid實例中只選擇屏幕上座標的任何項目。Flex Datagrid - 如何獲取鼠標x/y座標的項目?

我們在我們的Flash應用程序中實現右鍵功能,具有能夠向球門右鍵單擊DG行,這將選擇該行加上顯示包含一些背景命令的彈出窗口。

我設法得到正確的單擊事件爲我用this site幫助Flex應用程序。

進一步進展到目前爲止已經經由

var objects : Array = this.getObjectsUnderPoint(new Point(this.mouseX, this.mouseY)); 

獲得DataGrid實例,然後investige每個陣列的物品,對於那些「parent.parentList」指的是DataGrid實例中的一個。

現在我卡住 - 我無法找到任何一點至物品轉換器功能或任何東西。對我的方法的任何評論也非常受歡迎!

謝謝!

PS:使用標準的Flash ContextMenu,很遺憾,不是的一個選項。

回答

2
/** 
* Let mx and my be the mouse coordinates 
* (relative to the stage, not relative to the clicked object) 
* */ 

var len:Number = dg.dataProvider.length; 
var i:Number; 
var p1:Point; 
var p2:Point; 
var renderer:DisplayObject; 
for(i = 0; i < len; i++) 
{ 
    renderer = DisplayObject(dg.indexToItemRenderer(i)); 
    if(!renderer)//item is not displayed (scroll to view it) 
    continue; 
    p1 = new Point(renderer.x, renderer.y); 
    p2 = new Point(renderer.width, renderer.height); 
    p1 = renderer.parent.localToGlobal(p1); 
    p2 = renderer.localToGlobal(p2); 
    if(mx >= p1.x && mx <= p2.x && my >= p1.y && my <= p2.y) 
    { 
    trace("You clicked on " + dg.dataProvider.getItemAt(i)); 
    break; 
    } 
} 

您可以將ContextMenu附加到DataGrid的itemRenderer代替 - 這樣你可以從事件的currentTarget財產右擊的項目。儘可能簡單。

+0

沒有呢,可惜它不是。使用標準的Flex ContextMenu不是一種選擇,所以回到原點:「我的任務是在DataGrid實例中只選擇屏幕上座標的任何項目。」 – Tom 2009-11-25 07:49:54

+0

如果您能夠使用項目點下功能獲取數據網格,則您也應該能夠獲取項目渲染器。 – Amarghosh 2009-11-25 08:55:42

+0

試試這個代碼 - 沒有測試過,但應該工作。 – Amarghosh 2009-11-25 09:16:42

2

您可以使用itemRollOver事件(以及相關的爲itemRollOut),以保持最近的項目,該鼠標滑過的軌跡。只需將該項目保存在一個變量中。在顯示上下文菜單時,可以直接使用保存的項目,而不是嘗試根據(x,y)座標找到它。

1

這裏是事物的Flash端的完整的AS3代碼。請注意,您還需要在嵌入HTML中使用Javascript才能使其工作。

<?xml version="1.0" encoding="utf-8"?> 
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="horizontal" 
minWidth="1024" minHeight="768" 
creationComplete="onAppCreationComplete()" 
click="onRightClick()" 
> 
<mx:DataGrid 
    id="dgTest" 
    dataProvider="{['aaa','bbbbbbbbbbbbbbb']}" 
    > 
    <mx:columns> 
    <mx:DataGridColumn /> 
    </mx:columns> 
</mx:DataGrid> 

<mx:Script> 
<![CDATA[ 
    import mx.binding.utils.BindingUtils; 
    import mx.controls.Alert; 
    import mx.controls.Menu; 
    import mx.effects.Fade; 
    import mx.events.MenuEvent; 

    [Bindable] 
    public var customContextMenuItem : Object; 

    public var customContextMenu : Menu; 


    protected function onAppCreationComplete() : void 
    { 
    ExternalInterface.addCallback("rightClick", onRightClick); 
    this.customContextMenu = this.createCustomContextMenu(); 
    } 


    protected function onRightClick() : void 
    { 
    // find datagrid at mouse click coords 
    var dg : DataGrid = this.getDataGridFromObjectsUnderPoint(this.mouseX, this.mouseY); 
    if (dg) { 
    // if any, find clicked item 
    this.customContextMenuItem = this.findClickedItem(this.mouseX, this.mouseY, dg); 
    if (this.customContextMenuItem) { 
    // right clicking an item with the menu already showing does not show a new menu 
    // unless the previous one is hidden first 
    this.customContextMenu.hide(); 
    this.customContextMenu.show(this.mouseX+3, this.mouseY+2); 
    } 
    } 
    } 


    protected function getDataGridFromObjectsUnderPoint (x:Number, y:Number) : DataGrid 
    { 
    var objectsHere : Array = this.getObjectsUnderPoint(new Point(this.mouseX, this.mouseY)); 
    for each (var dispObj:DisplayObject in objectsHere) { 
    while (dispObj) { 
    if (dispObj is DataGrid) 
     return dispObj as DataGrid; 
    dispObj = dispObj.parent; 
    } 
    } 
    return null; 
    } 


    /** 
    * Returns a dataProvider item that displays at the given coords for the given dataGrid. 
    * Code provided by Stackoverflow user http://stackoverflow.com/users/165297/amarghosh, 
    * thanks a lot! 
    */ 
    protected function findClickedItem (x:Number, y:Number, dg:DataGrid) : Object 
    { 
    var p1 : Point; 
    var p2 : Point; 
    var renderer : DisplayObject; 

    for(var i:int=0; i<dg.dataProvider.length; i++) { 
    renderer = DisplayObject(dg.indexToItemRenderer(i)); 
    if (!renderer) //item is not displayed (scroll to view it) 
    continue; 
    p1 = new Point(renderer.x, renderer.y); 
    p2 = new Point(renderer.width, renderer.height); 
    p1 = renderer.parent.localToGlobal(p1); 
    p2 = renderer.localToGlobal(p2); 
    if(x >= p1.x && x <= p2.x && y >= p1.y && y <= p2.y) 
    return dg.dataProvider.getItemAt(i); 
    } 
    return null; 
    } 


    protected function createCustomContextMenu() : Menu 
    { 
    // create a dynamic-object as our first menu item entry, and use data binding 
    // to dynamically populate the 'title' value whenever our right-clicked item 
    // has changed 
    var menuItem : Object = new Object(); 
    menuItem.title = "default"; 
    BindingUtils.bindSetter(function (item:Object) : void { 
    trace(item); 
    menuItem.title = "Edit '" + item + "'"; 
    }, this, ["customContextMenuItem"]); 
    var dataProvider : Array = [ menuItem, {title:"Exit"} ]; 

    // create a nicely styled menu that looks very different to the standard Flash menu 
    var menu : Menu = Menu.createMenu(this, dataProvider, false); 
    menu.setStyle("fontWeight", "bold"); 
    menu.setStyle("backgroundColor", 0x000000); // standard back/foreground 
    menu.setStyle("color", 0xf0f0f0); 
    menu.setStyle("rollOverColor", 0x444444); // mouse hover back/foreground 
    menu.setStyle("textRollOverColor", 0xffffff); 
    menu.setStyle("selectionColor", 0x444444); // mouse click back/foreground 
    menu.setStyle("textSelectedColor", 0xe18c31); 
    menu.setStyle("openDuration", 0); 
    menu.labelField = "title"; 

    // we want to react to clicks in the menu 
    menu.addEventListener(MenuEvent.ITEM_CLICK, function (event:MenuEvent) : void { 
    Alert.show("Menu item clicked - clicked item title '" + event.item.title + "'"); 
    }); 

    // done 
    return menu; 
    } 
]]> 
</mx:Script> 
</mx:Application> 
0

dgdataGrid。 中DG的內容系統中的行的頂部的座標(即,從首部的底部)是:

var topOfRow:int = (int(dg.mouseY/dg.rowHeight) -1) * dg.rowHeight; 

現在可以調整到其它座標系: 例如至DG的系統:

topOfRow += dh.headerHeight; 

或使用localToGlobal()或其他。