Flex Datagrid - 如何获取鼠标 x/y 坐标的项目?

Posted

技术标签:

【中文标题】Flex Datagrid - 如何获取鼠标 x/y 坐标的项目?【英文标题】:Flex Datagrid - how to obtain item for mouse x/y coordinates? 【发布时间】:2010-12-19 21:10:30 【问题描述】:

我的任务是在 DataGrid 实例中选择一个项目,除了屏幕上的坐标之外什么都没有。

我们正在我们的 Flash 应用程序中实现右键单击功能,目标是能够右键单击 DG 行,这将选择该行并显示一个包含一些上下文命令的弹出窗口。

在this site 的帮助下,我设法将右键单击事件添加到我的 Flex 应用程序中。

到目前为止,进一步的进展是通过

获取DataGrid实例
var objects : Array = this.getObjectsUnderPoint(new Point(this.mouseX, this.mouseY));

然后调查数组的每个项目,因为其中一个“parent.parentList”指的是 DataGrid 实例。

现在我被困住了——我找不到任何点对项转换器功能或任何东西。到目前为止,任何关于我的方法的 cmet 都非常受欢迎!

谢谢!

PS:不幸的是,使用标准 Flash ContextMenu 不是一个选项。

【问题讨论】:

【参考方案1】:
/**
* 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 属性中获取右键单击的项目。尽可能简单。

【讨论】:

不,不幸的是它不是。使用标准的 Flex ContextMenu 不是一个选项,所以回到第一个问题:“我的任务是在 DataGrid 实例中选择一个项目,除了屏幕上的坐标之外什么都没有。” 如果你可以使用items-under-point函数获取datagrid,你应该也可以获取item renderer。 太棒了,就像一个魅力!我添加了完整代码的答案,见下文。谢谢老兄。【参考方案2】:

您可以使用itemRollOver 事件(以及相关的 itemRollOut)来跟踪鼠标经过的最新项目。只需将项目保存在变量中即可。当您显示上下文菜单时,您可以直接使用保存的项目,而不是尝试根据 (x,y) 坐标找到它。

【讨论】:

【参考方案3】:

这是 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 *** user http://***.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>

【讨论】:

【参考方案4】:

dgdataGrid。 dg 的内容系统中行的顶部坐标(即从标题的底部开始)是:

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

您现在可以调整到其他坐标系: 以dg的系统为例:

topOfRow += dh.headerHeight;

或使用localToGlobal() 或其他。

【讨论】:

以上是关于Flex Datagrid - 如何获取鼠标 x/y 坐标的项目?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Adob​​e Flex 中合并 DataGrid/Advanced DataGrid 中的单元格

从鼠标位置获取 DataGrid 单元格

Flex 3:如何在其 ItemRenderer 中获取 DataGridColumn 的 dataField?

如何在 Flex 中控制 Spark Datagrid 的滚动条位置?

以编程方式获取或设置 Datagrid 中的单元格值

如何在 Flex DataGrid 中结束/停止项目编辑