Ken, Thank you for the well-expressed response. I understand both options as you've explained them and will try them both to see which ones I end up having a better feel for. I may have to go for the second example as I think that it will get executed in a more deterministic order earlier - which is something that I will need to be reasonably assured of as the 'selectedWidget' value is one that is used by other KVO-triggered actions and that therefore lack of guaranteed order of setting can end up causing me problems.
On Friday, October 09, 2009, at 11:57PM, "Ken Thomases" <k...@codeweavers.com> wrote: >On Oct 9, 2009, at 5:08 PM, A B wrote: > >> Is there a way to bind an ivar to the currently selected object of a >> list which is being represented in an NSTableView via bindings? >> Unfortunately there does not seem to be a "selectedObject" key >> (though there is one for "selectedObjects"). Binding to the >> controller's "selection" doesn't really work as I'd expect and even >> if it did, I'd only be getting back a proxy object - which negates >> the purpose for which I want to use it, which is to call methods on >> the object. I had put in a hack which observes changes in >> selection, gets the selectedObjects list, checks for a count > 0, >> grabs the first and stuffs it into the ivar, etc. but not only does >> that feel really hackish, but doesn't always work. >> >> This would seem to be a pretty simple thing to want to do (i.e. >> present a list of objects, do things to/with the currently selected >> object) but I'm at somewhat of a loss to understand what I'm doing >> wrong. > >There's something just like this for NSPopUpButton. You bind its >'content' (and possibly 'contentObjects') binding to an indexed >collection property of the controller. Then you bind its >'selectedObject' binding to a to-one property of the controller. When >the pop-up is first set up, it displays the selected object as >originally set on the controller's to-one property. Then, as the user >selects items from the pop-up, the newly selected object is passed to >the setter for that to-one property. > >Strangely, there's nothing quite like that for NSArrayController. > >I think the best you can do is to bind the array controller's >selectionIndexes binding to an attribute of your coordinating >controller. (For illustration purposes, I'll call this attribute >property "selectedWidgetIndexes".) Then that coordinating controller >can have a "selectedWidget" to-one property which is set up to reflect >the object which is selected in the array controller. > >One way is to make the selectedWidget property computed-on-the-fly >based on the selection indexes: > >+(NSSet*)keyPathsForValuesAffectingSelectedWidget >{ > return [NSSet setWithObject:@"selectedWidgetIndexes"]; >} > >-(Widget*)selectedWidget >{ > if (![self.selectedWidgetIndexes count]) > return nil; > return [self.widgets objectAtIndex:[self.selectedWidgetIndexes >firstIndex]]; >} > >In this scenario, you don't actually have an ivar backing the >selectedWidget property. It's completely based off of the >selectedWidgetIndexes property and the "widgets" to-many property. >(The widgets property is assumed to be the indexed collection property >that the array controller is representing. The selectedWidgetIndexes >property can be a typical @synthesized copy property.) > >Another approach is to implement the setter for selectedWidgetIndexes >and use that to update the selectedWidget property directly. In this >case, selectedWidget isn't computed on the fly, but is actually held >(cached) in an ivar: > >-(void)setSelectedWidgetIndexes(NSIndexSet*)newSelectedWidgetIndexes >{ > if (![selectedWidgetIndexes isEqual:newSelectedWidgetIndexes]) > { > [selectedWidgetIndexes release]; > selectedWidgetIndexes = [newSelectedWidgetIndexes copy]; > if ([selectedWidgetIndexes count]) > self.selectedWidget = [self.widgets objectAtIndex: >[selectedWidgetIndexes firstIndex]]; > else > self.selectedWidget = nil; > } >} > >You don't need +keyPathsForValuesAffectingSelectedWidget since you're >going through the setter for the selectedWidget property. The >selectedWidget property can be a typical @synthesized retain property. > >By the way, notice that all of this discussion is in terms of the >array controller and the coordinating controller. No mention of the >table view because it's not directly relevant. The MVC design pattern >in action. ;) > >Regards, >Ken > > > _______________________________________________ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com