将NSArrayController绑定到NSPopupButton& NSTextField [英] Binding a NSArrayController to a NSPopupButton & NSTextField

查看:569
本文介绍了将NSArrayController绑定到NSPopupButton& NSTextField的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想要完成的事情似乎应该相当简单。我已在此处放置了一个示例项目。

What I want to accomplish seems like it should be fairly straightforward. I have placed a sample project here.

我有一个NSArrayController填充一个NSDictionaries数组。

I have a NSArrayController filled with an array of NSDictionaries.

[[self controller] addObject:@{ @"name" : @"itemA", @"part" : @"partA" }];
[[self controller] addObject:@{ @"name" : @"itemB", @"part" : @"partB" }];
[[self controller] addObject:@{ @"name" : @"itemC", @"part" : @"partC" }];

我使用基于'name'键的数组填充NSPopupButton。使用以下绑定很容易完成此操作。

I am populating a NSPopupButton with the items in this array based on the 'name' key. This is easily accomplished with the following bindings

然后,我想根据当前选择的NSPopupButton在'part'键中填充一个NSTextField文本。我已设置以下绑定:

I would then like to populate a NSTextField with the text in the 'part' key based on the current selection of the NSPopupButton. I have setup the following binding:

单独使用这些绑定,文本字段会显示partC。

With these bindings alone, the text field does display 'partC'.

但是,如果我更改NSPopupMenu的值,字段显示不会改变。

However, if I change the value of the NSPopupMenu, what the text field shows does not change.

我认为这只是一个问题,就是在NSPopupButton上设置Selected Object绑定

I thought this would simply be a matter of setting up the 'Selected Object' binding on the NSPopupButton

但这是不工作。我最终在我的菜单中的代理对象有一些奇怪的原因(提供了为什么会是一个奖金的原因)。

but that isn't working. I end up with the proxy object in my menu for some strange reason (providing the reason why would be a bonus).

那么,我需要做什么才能使这项工作?

So, what do I need to do to make this work?

推荐答案

在这种情况下不要使用选定对象。将弹出窗口的选定索引绑定绑定到NSArrayController的 selectionIndex 控制器密钥。

Don't use "Selected Object" in this case. Bind the pop-up's "Selected Index" binding to the NSArrayController's selectionIndex Controller Key. Tried it out on your sample project and it works.

编辑:

您问为什么要使用 selectionIndex over selectedObject 。第一些背景:

You asked why it's appropriate to use selectionIndex over selectedObject. First some background:

绑定弹出式菜单时,您可以绑定三个虚拟集合:内容应该在菜单中的事物 - 您必须始终指定内容。如果您既不指定内容对象也不指定内容值,则绑定到内容的值的集合将用作对象将使用 -description 方法返回的字符串作为值。换句话说,内容值是弹出窗口中显示的字符串,内容对象是它们对应的内容(这些内容可能不是字符串,没有适用于在弹出窗口中生成文本的 -description 方法)。这里需要注意的是,这里可能有三种不同的虚拟数组:内容的数组,内容对象的数组(可能不同)以及内容值(也可能不同)的数组。它们都具有相同数量的值,通常内容对象内容值将是 > Content 数组。

When binding a popup menu, there are three virtual "Collections" you can bind: Content is the abstract "list of things that should be in the menu" -- you must always specify Content. If you specify neither Content Objects, nor Content Values, then the collection of values bound to Content will be used as the "objects" and the strings returned by their -description methods will be used as the "values". In other words, the Content Values are the strings displayed in the pop-up and the Content Objects are the things they correspond to (which are possibly not strings, and which might not have a -description method suitable for generating the text in the pop-up). What's important to realize here is that there are potentially three different 'virtual arrays' in play here: The array for Content, the array for Content Objects (which may be different) and the array for Content Values (which may also be different). They will all have the same number of values, and typically, the Content Objects and Content Values will be functions (in the mathematical sense) of the corresponding items in the Content array.

接下来需要意识到的是 NSArrayController 生活中的目的是跟踪用户的选择。这只是轻微地(如果有的话)在弹出窗口的情况下有趣,但在 NSTableView 的情况下开始变得更有趣。在内部, NSArrayController 通过保留包含内容中的索引的 NSIndexSet 阵列在任何给定时间被选择。为了方便起见,选择状态以几种不同的方式显示:

The next thing that's important to realize is that part of NSArrayController's purpose in life is to keep track of the user's selection. This is only mildly (if at all) interesting in the case of a pop-up, but starts to become far more interesting in the case of an NSTableView. Internally, NSArrayController keeps track of this by keeping an NSIndexSet containing the indexes in the Content array that are selected at any given time. From there, selection state is exposed in several different ways for your convenience:


  • selectionIndexes 数组中的所选项目的索引的 NSIndexSet

  • selectionIndex 是不支持多选的应用程序的一个方便的选项。可以认为它等效于 arrayController.selectionIndexes.firstIndex

  • selectedObject 在单选情况下也很有用,在概念上对应于 ContentObjectsArray [arrayController.selectionIndexes.firstIndex]

  • selection 返回一个特殊对象(对消费者不透明),它在内容数组中读取和写回底层对象(或多个选择情况下的对象)强>阵列控制器。它存在于在多个选择情况下能够一次编辑多个对象,并且为其他特殊情况提供支持。 (你应该把这个属性看作是只读的;由于它的类型对于消费者来说是不透明的,所以你永远不能创建一个合适的新值来编写它:。 - [arrayController .selection setValue:myObject forKey:@modelKey] ,但是它不是有意义的调用像 - [arrayController setValue:myObject forKey:@ selection]

  • selectionIndexes is as described - an NSIndexSet containing the indexes of the selected items in the Content array
  • selectionIndex is a convenient option for applications that do not support multiple selection. It can be thought of as being equivalent to arrayController.selectionIndexes.firstIndex.
  • selectedObject is also useful in single selection cases, and corresponds conceptually to ContentObjectsArray[arrayController.selectionIndexes.firstIndex]
  • selection returns a special object (opaque to the consumer) that brokers reads and writes back to the underlying object (or objects in the case of multiple selection) in the Content Array of the array controller. It exists to enable editing multiple objects at a time in multiple selection cases, and to provide support for other special cases. (You should think of this property as read-only; Since its type is opaque to the consumer, you could never make a suitable new value to write into it. It's meaningful to make calls like: -[arrayController.selection setValue: myObject forKey: @"modelKey"], but it's not meaningful to make calls like -[arrayController setValue: myObject forKey: @"selection"]

根据对选择的理解属性,让我们退一步看看为什么这是不正确的使用在这种情况下。 NSPopUpButton 试图聪明:你提供它应通过内容内容值绑定在菜单中显示的事件列表,然后您还要求您绑定其选定对象 NSArrayController 选择属性你可能认为这是一个 绑定 - 即亲爱的弹出窗口,请采取用户的选择,并推送到arrayController,但绑定是真正的双向。因此,当绑定刷新时,弹出菜单首先使用内容/内容值绑定中的所有项目填充菜单,然后它说:哦,你说 arrayController.selection 是我的选择对象,这很奇怪 - 它不在我的内容/内容值最好将它添加到列表中,我会通过调用 -description ,并将该字符串插入菜单中。但是,从选择对象绑定中获得的对象是上述不透明选择对象(您可以从结果中看到它是类 _NSControllerObjectProxy

With that understanding of the selection property, let's take a step back and see why it's not the right thing to use in this case. NSPopUpButton tries to be smart: You've provided it with a list of things that should be in the menu via the Content and Content Values bindings. Then you've additionally told it that you want to bind its Selected Object to the the NSArrayController's selection property. You're probably thinking of this as a "write only" binding -- i.e. "Dear pop-up, please take the user's selection and push it into the arrayController", but the binding is really bi-directional. So when the bindings refresh, the popup first populates the menu with all the items from the Content/Content Values bindings, and then it says, "Oh, you say the value at arrayController.selection is my Selected Object. That's odd -- it's not in the list of things bound with my Content/Content Values bindings. I'd better add it to the list for you! I'll do that by calling -description on it, and plunking that string into the menu for you." But the object you get from that Selected Object binding is the opaque selection object described above (and you can see from the outcome that it is of class _NSControllerObjectProxy, a private-to-AppKit class as hinted by the leading underscore).

总之, 为什么绑定弹出框的选择对象绑定到数组控制器的选择控制器密钥是错误的事情。可悲的是,但是我相信你已经发现,Cocoa绑定的文档只是开始划伤表面,所以不要感觉不好。我几年来一直在一个大型项目中使用Cocoa绑定几年,我仍然觉得有很多用例我还不完全明白。

In sum, that's why binding your popup's Selected Object binding to the array controller's selection controller key is the wrong thing to do here. Sad to say, but as I'm sure you've discovered, the documentation for Cocoa bindings only begins to scratch the surface, so don't feel bad. I've been working with Cocoa bindings pretty much daily, in a large-scale project, for several years now, and I still feel like there are a lot of use cases I don't yet fully understand.

这篇关于将NSArrayController绑定到NSPopupButton& NSTextField的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆