Search code examples
cocoacore-datacocoa-bindingsnsarraycontroller

NSArrayController binding to One-To-Many relationship in a NSTableView


I'm working on an application using Core Data. My model is basically a list of objects, which are called "Descriptions". Each description has a list of "Properties". This is a really simple one-to-many relationship. I have a NSTableView who contains 2 columns.

I'm using binding to fill my table view with the list of my properties :

self.controller = [[NSArrayController alloc] initWithContent: self.descriptionObject.properties];

NSTableColumn *propertyColumn = [self.propertiesTableView tableColumnWithIdentifier: @"property_column"];
[propertyColumn bind: NSValueBinding toObject: self.controller withKeyPath: @"arrangedObjects.name" options: nil];

NSTableColumn *infoColumn = [self.propertiesTableView tableColumnWithIdentifier: @"info_column"];
[infoColumn bind: NSValueBinding toObject: self.controller withKeyPath: @"arrangedObjects.info" options: nil];

I have a button that calls my "addProperty" method :

- (IBAction)addProperty:(id)sender {
    NSLog(@"Add a new property");

    PCSDescriptionProperty *property = [PCSDescriptionProperty insertInManagedObjectContext: self.storage.managedObjectContext];
    property.name = @"New property";
    property.info = @"New property info";

    [self.descriptionObject addPropertiesObject: property];
}

The problem is, calling addPropertiesObject: does not trigger a KVO notification and my tableview is not refreshed. I've tried calling willChangeValueForKey/didChangeValueForKey before and after with addPropertiesObject without success.

Any idea why ? Thanks !


Solution

  • Thanks to Duncan Groenewald, here what I did : I stopped using initWithContent: and actually bound my set of properties to the NSContentSet of my ArrayController :

    self.controller = [[NSArrayController alloc] init];
    [self.controller bind: NSContentSetBinding toObject: self.apiDescription withKeyPath: @"properties" options: nil];
    

    Then, in my addProperty: method, all I add to do was to reverse the way I added my new property to my description one :

    property.descriptionObject = self.descriptionObject;