views:

988

answers:

2

I'm trying out some MacOS programming and having some trouble understanding how bindings work with an NSPopupButton. I'm interested in binding to an NSDictionaryController (I don't think I need an intermediate NSArrayController but if that is the best way, I'm open to it).

I've created a controller object that has a property 'db' which has a property 'species' which is an NSMutableDictionary. The 'species' dictionary has ID's for keys and Species objects for values. Species objects have a description property. In InterfaceBuilder, I've created MyController, NSDictionaryController, and an NSPopupButton. I would like to populate the popup with Species.descriptions. When selected, I need access to the corresponding ID.

I've setup the NSDictionaryController to bind 'Content Dictionary' to MyController with Model Key Path 'db.species'. With NSPopupButton, so far I've bound 'Content Values' to NSDictionaryController with controller key 'arrangedObjects' and Model Key Path set to 'value.description'.

This seems to work getting the list populated. My main question is what the best way to wire up the selection is. Ideally, I would like to wire selection to the NSDictionaryController so that I can use the NSDictionaryController to access the selection. One reason for this is so that I can wire other controls to the NSDictionaryController to see the current selection. If not, should I wire to a property in MyController or something? Just looking for the best practices. I would like as much to be through the Interface Builder mechanisms so that I can easily reuse the model and controller design in another application with a different view.

Update using Brian's answer as guidance:

NSPopupButton: bind Content to NSDictionaryController->arrangedObjects->value.description

bind Content Objects to NSDictionaryController->arrangedObjects->key

bind Selected Index to NSDictionaryController->selectionIndex

bind NSDictionaryController->db.species

Everything seems to work. I can grab the object from the controller with [[[controller selectedObjects] lastObject] value]. It's in an array of selected objects with key, value pairs, I believe.

+2  A: 

I've never tried this with an NSDictionaryController, but I think you would want to bind the contentObjects of the pop-up to the dict controller's "arrangedObjects.key" and the selectedObject binding to the dict controller's "selection" key. The contentObjects binding would specify the IDs as being the underlying objects represented by each menu item. Then when an item is selected from the pop-up, the selectedObject binding would set the ID corresponding to that menu item as the selection of the dict controller.

Brian Webster
+1  A: 

I would like to populate the popup with Species.descriptions. When selected, I need access to the corresponding ID.

Bind content to the dictionary controller's arrangedObjects.value (don't include description—the pop-up button will do that for you) and contentObjects to the dictionary controller's arrangedObjects.key.

For more info, see NSPopUpButton in the Cocoa Bindings Reference.

(I notice it describes content as “An NSArrayController instance …”. Dictionary controllers are array controllers, so that shouldn't be a problem, but binding to a property of the controller may be. Something to watch out for.)

Peter Hosey