Re: Binding to currently selected object in a list?
Re: Binding to currently selected object in a list?
- Subject: Re: Binding to currently selected object in a list?
- From: Ken Thomases <email@hidden>
- Date: Sat, 10 Oct 2009 01:57:17 -0500
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 (email@hidden)
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:
This email sent to email@hidden