基于NSTableViewCell的上下文菜单

sha*_*rgy 9 cocoa contextmenu objective-c nstableview nstableviewcell

我想把一个上下文菜单放到一个NSTableView.这部分完成了.我要做的就是根据右键单元格的内容显示不同的菜单条目,而不显示特定列的上下文菜单.

这是:

第0列,第1列没有上下文菜单

所有其他单元格应该具有如下的上下文菜单:

第一个条目:"删除"samerow.column1.value
第二个条目:"save"samecolumn.headertext

希望问题很清楚..

谢谢

-编辑-

右边的那个是上下文菜单对于任何给定单元格应该是什么样子.

在此输入图像描述

War*_*ton 36

这是代表! - 不需要子类

在IB中,如果你拖到NSTableView窗口/视图上,你会注意到menu桌子的出口.

因此,实现上下文菜单的一种非常简单的方法是将该出口连接到存根菜单,并将菜单的委托出口连接到实现NSMenuDelegate协议方法的对象- (void)menuNeedsUpdate:(NSMenu *)menu

界面生成器屏幕截图

通常,菜单的委托是为表提供数据源/委托的同一对象,但它也可能是拥有该表的视图控制器.

有关这方面的更多信息,请查看文档

你可以在协议中做一堆聪明的东西,但是一个非常简单的实现可能如下所示

#pragma mark tableview menu delegates

- (void)menuNeedsUpdate:(NSMenu *)menu
{
NSInteger clickedrow = [mytable clickedRow];
NSInteger clickedcol = [mytable clickedColumn];

if (clickedrow > -1 && clickedcol > -1) {



   //construct a menu based on column and row   
   NSMenu *newmenu = [self constructMenuForRow:clickedrow andColumn:clickedcol];

   //strip all the existing stuff       
   [menu removeAllItems];

   //then repopulate with the menu that you just created        
   NSArray *itemarr = [NSArray arrayWithArray:[newmenu itemArray]];
   for(NSMenuItem *item in itemarr)
   {
      [newmenu removeItem:[item retain]];
      [menu addItem:item];
      [item release];
   }        
}

}
Run Code Online (Sandbox Code Playgroud)

然后是构建菜单的方法.

-(NSMenu *)constructMenuForRow:(int)row andColumn:(int)col
{

    NSMenu *contextMenu = [[[NSMenu alloc] initWithTitle:@"Context"] autorelease];

NSString *title1 = [NSString stringWithFormat:@"Delete %@",[self titleForRow:row]]; 

NSMenuItem *item1 = [[[NSMenuItem alloc] initWithTitle:title1 action:@selector(deleteObject:) keyEquivalent:@""] autorelease];
    [contextMenu addItem:item1];
    //
NSString *title2 = [NSString stringWithFormat:@"Save %@",[self titleForColumn:col]];    

NSMenuItem *item2 = [[[NSMenuItem alloc] initWithTitle:title1 action:@selector(saveObject:) keyEquivalent:@""] autorelease];
    [contextMenu addItem:item2];

return contextMenu;
}
Run Code Online (Sandbox Code Playgroud)

你如何选择实施titleForRow:titleForColumn:达到你.

请注意,NSMenuItem提供的属性representedObject允许您将任意对象绑定到菜单项,从而将信息发送到您的方法(例如deleteObject:)

编辑

注意 - - (void)menuNeedsUpdate:(NSMenu *)menuNSDocument子类中实现将停止出现在10.8中出现的标题栏中的自动保存/版本菜单.

它仍然适用于10.7所以去图.在任何情况下,菜单委托都需要是您的NSDocument子类以外的东西.