如何在NSPopUpButton的菜单中绑定基于视图的NSMenuItem?

时间:2014-07-06 02:07:29

标签: cocoa cocoa-bindings nsarraycontroller nsmenuitem nspopupbutton

设置一个包含字符串的NSArray并将内容数组连接到NSPopUpButton(这个标准问题的一个很好的答案就在这里,NSPopUpButton + Bindings + Show All Option),这是微不足道的。

我有一个NSPopUpButton并希望菜单中的每个项目都使用视图进行绘制(可以使用NSMenuItem的-setView:方法将视图添加到10.5以来的菜单项。)

到目前为止,我有以下方法。

1)提供视图的模型对象

@interface MenuViewsModel : NSObject
// Array of views for the pop up button to display
@property NSArray *previewViews; 
@end

2)在IB中,我将一个数组控制器添加到我的XIB中,并将其内容数组设置为模型的previewViews

3)接下来,我将NSPopUpView绑定到阵列控制器:

  • 内容 - > arrayController.arrangedObjects
  • 内容值 - > arrayController.arrangedObjects

弹出菜单将视图的指针显示为字符串,而不是获取视图并设置NSMenuItem的view属性。例如,弹出按钮显示诸如

之类的项目
  

< NSView:0x61000014e910>

     

< NSView:0x61000014e9c0>

1 个答案:

答案 0 :(得分:0)

你太接近完成了。你需要做的是arrayController.arrangedObjects。[insertModelDisplayProperty]

我还没有足够的代表发布图片...否则我会给你一个屏幕截图 - 我正在解决这个问题,并让它发挥作用。

在XIB设计器中,ControlValues的绑定设置中将有一个modelKeyPath属性。将模型键路径值设置为要为每个项目显示的属性。

我有一个更简单的问题要解决,但需要类似的方法......我仍然使用绑定;但是。

stevesliva的评论让我思考。我需要为每个菜单项进行简单的样式更改;所以我派生了我自己的NSMenu,取而代之的是NSPopupButton包裹的那个。我要覆盖的重要方法是:

- (NSMenuItem *)insertItemWithTitle:(NSString *)aString
                         action:(SEL)aSelector
                  keyEquivalent:(NSString *)keyEquiv
                        atIndex:(NSInteger)index

if((aString != nil)  && ([aString length] > 0))
{
    NSMenuItem *result = [[NSMenuItem alloc] initWithTitle:aString action:aSelector keyEquivalent:keyEquiv];

    NSView *menuView =[[AppMenuItemView alloc] init];

    menuView.autoresizingMask = NSViewWidthSizable;

    [result setView: menuView];

    [self insertItem:result atIndex:index];

    return result;
}
else
{
    return [super insertItemWithTitle:aString action:aSelector keyEquivalent:keyEquiv atIndex:index];
}

}


如果我们扩展我使用的字符串比较,你可以很容易地看到史蒂夫的想法是如何合理的......在这个逻辑中,你可以使用“标题”作为视图字典的关键,然后在这里使用分配每个项目的视图属性。

请注意,这可能需要更改您的建模方式 - 这些视图可能必须绑定到单例,或者其他一些关联对象内存的方式...不要说这部分是微不足道的......但是,它可能。最后,这可能是一个值得重新努力的问题。请注意,addItemWithTitle方法可能需要以与insertItemWithTitle方法类似的方式进行编码。

将所有这些结合在一起,是的...绑定对于这个用例可能不值得,你的原始帖子应该被投票(如果我能用我微不足道的声誉实际投票)。