如何获取在 NSOutlineView 的上下文菜单中右键单击的元素?

Posted

技术标签:

【中文标题】如何获取在 NSOutlineView 的上下文菜单中右键单击的元素?【英文标题】:How can I get the element that was right-clicked in a context menu on a NSOutlineView? 【发布时间】:2013-04-16 08:54:23 【问题描述】:

我有一个NSOutlineView,并且还创建了一个菜单,当我右键单击任何元素时,它会显示为上下文菜单。

现在我有两个问题。

    如何识别右键单击的元素,以便对上下文菜单中的任何功能采取相应的行动。 如何在实际打开上下文菜单之前更改上下文菜单,以根据右键单击的元素删除或禁用菜单项?

【问题讨论】:

【参考方案1】:

clickedRow 方法(继承自 NSTableView)将为您提供行号。

然后可以使用NSOutlineViewitemForRow 将行号转换为项目。

对于菜单部分,NSMenuDelegate方法menu:updateItem:atIndex:shouldCancel:在菜单显示之前被调用,所以你可以根据需要进行修改。

根据docs,你还得实现numberOfItemsInMenu:

您可以将相同的对象设置为大纲视图和菜单的委托。

【讨论】:

我添加了一个 并实现了 方法但没有调用该方法?!我错过了什么吗? 有效。我有 FileOwner 的委托,这是我的主要 ViewController 使用了自动补全“ESC”。我会忽略一个错字。 让我们continue this discussion in chat【参考方案2】:

理论上,当右键单击一行时,它应该已经是 NSOutlineView 中选择的行。无论如何,这不会正常发生。

我已经通过实现以下方法解决了这个问题(也回答了第二个问题):

- (void)menuNeedsUpdate:(NSMenu *)menu

在您的一个类中插入此方法并将该类注册为菜单委托(请注意:NSMenu,而不是单个 NSMenuItem)。在上面的代码中,我添加了这段代码,用于在右键单击时自动选择单击的行。

if ([[arrayController selectedObjects] count] == 0 || [[arrayController selectedObjects] count] == 1) 
        if ([myTable clickedRow] != -1) 
            [myTable selectRowIndexes:[NSIndexSet indexSetWithIndex:[myTable clickedRow]] byExtendingSelection:FALSE];
        
    

据我所知,这在 NSTableView 中可以正常工作,因此它也应该在您的 NSOutlineView 中工作。

关于第二个问题,你可以使用上面的方法在每次显示NSMenu时得到通知。

【讨论】:

整个 OS X 的默认行为是不自动选择通过鼠标右键单击的项目(上下文菜单)

以上是关于如何获取在 NSOutlineView 的上下文菜单中右键单击的元素?的主要内容,如果未能解决你的问题,请参考以下文章

如何在基于视图的 NSOutlineView 中自定义 groupItem-look?

如何有效地展平 NSOutlineView?

如何遍历我的 NSOutlineView 的所有项目?

如何将 NSOutlineView 与多个核心数据实体作为组一起使用

从 NSOutlineView 中拖放

NSOutlineView 控制高亮和缩进