【问题标题】:How to get the tree-view item which triggered a popup menu?如何获取触发弹出菜单的树视图项?
【发布时间】:2013-12-25 13:37:37
【问题描述】:

这可能是一个愚蠢的问题,但我有一个与许多 TTreeViewItems 链接的弹出菜单。问题是 TTreeView.Selected 属性永远不会在右键单击时设置。 GetMousePos 容易返回下一个或上一个 TTreeViewItem 的坐标。如何获取实际触发弹窗的 Item?

【问题讨论】:

  • TPopupMenu.PopupPoint 是更好的查询方式。
  • @FreeConsulting 显而易见的方式,但它返回 (0,0) 点:)
  • 是的,我刚刚验证...

标签: delphi firemonkey firemonkey-fm2


【解决方案1】:

您可以像这样使用 TPopupMenu 的 OnPopup 事件:

procedure TForm7.PopupMenu1Popup(Sender: TObject);
var
  aNode: TTreeNode;
  p: TPoint;
begin
  p := TreeView1.ScreenToClient(PopupMenu1.PopupPoint);
  aNode := TreeView1.GetNodeAt(p.X, p.Y);
  if aNode <> Nil then
    caption := aNode.Text;
end;

【讨论】:

  • 我要的是 firemonkey 而不是 vcl。
【解决方案2】:

似乎TPopupMenu.PopupPoint 在您单击PopupMenu 中的项目时返回(0,0) 点(在Delphi XE2 中,docwiki 说它在内部用于设置菜单的位置,并且似乎设置为0当菜单消失时)。 所以在这种情况下,在我看来,最简单的方法是处理TreeView.OnMouseDown,您可以在其中保存对选定项目的引用,然后在弹出项目事件处理程序中使用它;

所以,在下面的示例代码中,我已将 FClickedItem : TTreeViewItem 添加到表单类中;

procedure TSampleForm.SampleTreeViewMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Single);
begin
    if button = TMouseButton.mbRight then
         FClickedItem := SampleTreeView.ItemByPoint(x,y)
    else FClickedItem := nil;
end;

procedure TSampleForm.TestMenuItemClick(Sender: TObject);
begin
    if Assigned(FClickedItem) then
         ShowMessage(Format('Item `%s (%s)` was selected!', [FClickedItem.Text, FClickedItem.Name]))
    else ShowMessage('there is nothing to show');
end;

更新:我刚刚浏览了源代码,私有变量TPopupMenu.FPopupPoint(只读属性)没有在实现代码中使用,所以它总是=(0,0)

【讨论】:

  • 这应该可以,但是菜单键(在 Windows 平台上)呢?
  • 它确实以一种迂回的方式工作,实际上我试图避免这种情况,但与往常一样,可感知的优雅解决方案只不过是黑洞。
  • @TLama 好问题,但我实际上不知道如何处理 ContextMenu 按键 :) OnKeyDown 按下键盘上的菜单键时不会触发事件处理程序:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-16
  • 1970-01-01
  • 2016-04-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多