2009-08-21 123 views
18

如何添加在NSOutlineView中右键单击某行的能力,以便您可以说删除对象或其他活动。 (即就像当你右击在Apple Mail应用程序的文件夹上)如何添加上下文感性菜单到NSOutlineView(即右键单击菜单)

我想我走了一半,我有NSOutlineView的一个子类,让我赶上点击右键,显示基于上下文菜单选中的行而不是鼠标点击的行。

@implementation NSContextOutlineView 

    - (NSMenu *)defaultMenu { 
     if([self selectedRow] < 0) return nil; 
     NSMenu *theMenu = [[[NSMenu alloc] initWithTitle:@"Model browser context menu"] autorelease]; 
     [theMenu insertItemWithTitle:@"Add package" action:@selector(addSite:) keyEquivalent:@"" atIndex:0]; 
     NSString* deleteItem = [NSString stringWithFormat: @"Remove '%i'", [self selectedRow]]; 
     [theMenu insertItemWithTitle: deleteItem action:@selector(removeSite:) keyEquivalent:@"" atIndex:1]; 
     return theMenu; 
    } 

    - (NSMenu *)menuForEvent:(NSEvent *)theEvent { 
     return [self defaultMenu]; 
    } 
@end 

对不起,如果答案是显而易见的我只是不能找到任何帮助这个在线或在文档中。

感谢void对于答案,这导致我使用这个:

- (NSMenu *)menuForEvent:(NSEvent *)theEvent { 
    NSPoint pt = [self convertPoint:[theEvent locationInWindow] fromView:nil]; 
    id item = [self itemAtRow: [self rowAtPoint:pt]]; 
    return [self defaultMenuFor: item]; 
} 
+0

没有运行它,看起来它应该工作得很好。不是吗?如果不是,你有什么问题呢? – 2009-08-21 03:10:01

+4

另外,不要在你自己的类上使用NS前缀。如果Apple向将来的Cocoa版本添加NSContextOutlineView类,它们的类和你的类将发生冲突,并且你的应用程序可能不会运行。 – 2009-08-21 03:10:48

+1

我认为发布代码的问题是它将使用selectedRow,而不是执行右/ ctrl单击的行。这可能是也可能不是选定的行。 – VoidPointer 2009-08-21 16:40:24

回答

21

在你menuForEvent方法,你可以找出发生在哪一行的点击。您可以传递一个作为参数传递给你的defaultMenu方法 - 也许称之为defaultMenuForRow:

-(NSMenu*)menuForEvent:(NSEvent*)evt 
{ 
    NSPoint pt = [self convertPoint:[evt locationInWindow] fromView:nil]; 
    int row=[self rowAtPoint:pt]; 
    return [self defaultMenuForRow:row]; 
} 

现在你可以建立你在事件中发现该行的菜单......

-(NSMenu*)defaultMenuForRow:(int)row 
{ 
    if (row < 0) return nil; 

    NSMenu *theMenu = [[[NSMenu alloc] 
           initWithTitle:@"Model browser context menu"] 
           autorelease]; 
    [theMenu insertItemWithTitle:@"Add package" 
          action:@selector(addSite:) 
        keyEquivalent:@"" 
         atIndex:0]; 
    [theMenu insertItemWithTitle:[NSString stringWithFormat:@"Remove '%i'", row] 
          action:@selector(removeSite:) 
        keyEquivalent:@"" 
         atIndex:0]; 
    // you'll need to find a way of getting the information about the 
    // row that is to be removed to the removeSite method 
    // assuming that an ivar 'contextRow' is used for this 
    contextRow = row; 

    return theMenu;   
} 

此外,正如在评论中已经提到的,你真的不应该在你自己的类上使用NS前缀。有在未来再加上它会混淆大家,期待你的代码的冲突潜在的 - 包括你自己:)

希望这有助于...

+0

非常感谢!所以很多这些事情都很简单,但只有一次你知道如何! – Jacob 2009-08-22 02:15:40

+0

伤心,我们需要继承'NSOutlineView'来实现这一点。此功能应该已包含在委托协议中:-) – 2017-08-20 12:52:18

-1

如果你愿意,你可以附加菜单单个电池观点或行观点,并建立与接口生成器:

@implementation BSMotleyOutlineView 

-(NSMenu *)menuForEvent:(NSEvent *)event 
{ 
    NSPoint pt = [self convertPoint:[event locationInWindow] fromView:nil]; 
    NSInteger row = [self rowAtPoint:pt]; 
    if (row >= 0) { 
     NSTableRowView* rowView = [self rowViewAtRow:row makeIfNecessary:NO]; 
     if (rowView) { 
      NSInteger col = [self columnAtPoint:pt]; 
      if (col >= 0) { 
       NSTableCellView* cellView = [rowView viewAtColumn:col]; 
       NSMenu* cellMenu = cellView.menu; 
       if(cellMenu) { 
        return cellMenu; 
       } 
      } 
      NSMenu* rowMenu = rowView.menu; 
      if (rowMenu) { 
       return rowMenu; 
      } 
     } 
    } 
    return [super menuForEvent:event]; 
} 
@end 
8

下面是使用一个子类,并扩展了默认NSOutlineDelegate这样你就可以在委托定义菜单一雨燕2.0的例子。

protocol MenuOutlineViewDelegate : NSOutlineViewDelegate { 
    func outlineView(outlineView: NSOutlineView, menuForItem item: AnyObject) -> NSMenu? 
} 

class MenuOutlineView: NSOutlineView { 

    override func menuForEvent(event: NSEvent) -> NSMenu? { 
     let point = self.convertPoint(event.locationInWindow, fromView: nil) 
     let row = self.rowAtPoint(point) 
     let item = self.itemAtRow(row) 

     if (item == nil) { 
      return nil 
     } 

     return (self.delegate() as! MenuOutlineViewDelegate).outlineView(self, menuForItem: item!) 
    } 

} 
相关问题