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: A B <email@hidden>
- Date: Sat, 10 Oct 2009 10:06:11 -0700
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" <email@hidden> 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 (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