I have an NSOutlineView with checkboxes. I have the checkbox state bound to a node item with the key shouldBeCopied.
Are you binding the column or the cell? You should bind the column.
-(BOOL)shouldBeCopied {
if([[self parent] shouldBeCopied])
return YES;
return shouldBeCopied;
}
Would it not be better to use the child's value first? If nothing else, it's cheaper to retrieve (no message required).
The amended getter would then look like this:
- (BOOL) shouldBeCopied {
return (shouldBeCopied || [[self parent] shouldBeCopied]);
}
The problem I'm having is that when I check the parent, it does not update that view of the children if they are already expanded.
There are two solutions. One is cleaner and will work on 10.5 and later. The other is slightly dirty and will work on any version of Mac OS X.
The dirty solution is to have the parent, from the setter method, post KVO notifications on behalf of all of its children. Something like:
[children performSelector:@selector(willChangeValueForKey:) withObject:@"shouldBeCopied"];
//Actually change the value here.
[children performSelector:@selector(didChangeValueForKey:) withObject:@"shouldBeCopied"];
This is dirty because it has one object posting KVO notifications about a property of another object. Each object should only claim to know the values of its own properties; an object that claims to know the values of another object's properties risks being wrong, leading to wrong and/or inefficient behavior, not to mention a propensity for the code to induce headache.
The cleaner solution is to have each object observe this property of its parent. Pass the NSKeyValueObservingOptionPrior
option when adding yourself as an observer in order to get a notification before the change (which you'll respond to, in the observation method, by sending [self willChangeValueForKey:]
) and a notification after the change (which you'll respond to, in the observation method, by sending [self didChangeValueForKey:]
).
With the clean solution, each object only sends KVO notifications about its own property changing; no object is posting notifications about other objects' properties.
You might be tempted to have the child not send itself these KVO notifications when its own value for the property is YES
, because in that case the parent's value doesn't matter. You shouldn't, though, as this would only work for children; if a farther-down descendant has the property set to NO
, then that object's ancestors' values matter after all, and that object will only get the notification if every one of its ancestors posts it.