开发者

NSTableView content based on a selection of another NSArrayController

The issue

I have a popup button (NSPopUpButton) that is bound to an NSArrayController. This array controller handles parent objects that each have a collection of child objects. I have an NSTableView in which I need to show these children for the selected item in popup. In addition, the list of children needs to be manipulated (add/remove).

I've tried to accomplish this in many ways but always run into some thing that complicates the solution. What is the best way to implement this?

The data is managed here by Core Data and thus, the collections are NSSets. I've tried adding a conversion method in the parent to return a sorted NSArray (in order to bind it with NSArrayController) but this approach prevents the KVO and the array controller is not updated properly.

Thank you in advance.

An example

To clarify, here's a hypothetic example:

Let's say I 开发者_如何学Pythonhave a list of countries that is maintained elsewhere. One of these countries is selected in a popup button. Each country has a set of cities. When a country is selected a table view is populated by it's cities.


There is a solution for this without the delegate/datasource setup.

My context is this:

  • CoreData model with Parents and Children, one Parent has multiple Children via a relationship named children. Both have a attribute name.
  • The two Entities must be available as classes (each with a .m and a .h). (Xcode will write them for you if you go to File-New-File-CoreData-NSManagedObjectSubclass.) Now the ChildObjects of a ParentObject can be accessed by ParentObject.children
  • Two NSArrayControllers: ParentArrayController and ChildArrayController.
  • Two NSTableViews: ParentTable and ChildTable, each with one column for name. (It should not matter whether you use a Popup or a table as long as it's controlled by a NSArrayController.)

The steps to take are as follows:

  • Connect both NSArrayControllers to the MangagedObjectContext as usual and set them to Mode: Entity Name with their respective Entity (Parent or Child)
  • Bind both TableViews (their columns) to their NSArrayController as usual.
  • Now comes the magic: In the ChildArrayControllers binding section under ControllerContent-ContentSet bind to the ParentArrayController with ControllerKey: selection and ModelKeyPath: children.

Done. If you select a ParentObject in the ParentTable the ChildTable shows its children.

To add and remove children to parents you can use the (void)addChildrenObject:(Child *)value; method that Xcode wrote for you in the Parents.m class file.


I didn't find any way to implement this by simply with dragging and dropping. I had to implement a delegate and data source for the table of cities (from the example). The window controller is notified of the selection changes in the popup button and this updates the content on the table view delegate / data source.

I actually feel this is little bit better way to implement the issue (than with bindings and array controllers) since it gives more control over special cases.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜