Re: Binding an Array of Dictionaries
Re: Binding an Array of Dictionaries
- Subject: Re: Binding an Array of Dictionaries
- From: "Gerriet M. Denkmann" <email@hidden>
- Date: Mon, 14 Dec 2009 02:28:50 +0700
On 13 Dec 2009, at 23:50, Keary Suska wrote:
> On Dec 12, 2009, at 10:35 PM, Gerriet M. Denkmann wrote:
>
>> Well, not quite.
>> As I stated in some previous post in this thread, the NSDictionaryController (bound to "currentDictionary") fills an editable NSTableView.
>> And if the user edits some key or value in this NSTableView the NSDictionaryController does NOT update "currentDictionary", but replaces it with another NSDictionary.
>
> Forgot about that. Instead, I would recommend:
>
> 0. observe NSArrayController's "selectionIndex"
> 1. I am assuming that the observing object owns the array that is the content for the array controller. If not, then you need a reference to the owning object, used instead of "self" below. I am calling the content array "contentArray".
> 2. You will only have one property: "selectedDictionary", not an instance variable, but you implement the accessors yourself (see below)
>
> observeValueForKeyPath tells you when the selection changes:
>
> - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
> {
> // if you have a specific context, you don't need to check the key name
> if( object == arrayController && context == kSelectedDictionary )
> {
> // when the selection changes, so does the selectedDictionary property.
> [self willChangeValueForKey:@"selectedDictionary"];
> [self didChangeValueForKey:@"selectedDictionary"];
> }
> else
> {
> [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
> }
> }
>
>
> Implement selectedDictionary accessors:
Here is the code I am now using:
- (NSDictionary *)selectedDictionary
{
NSArray *arrangedObjects = [ arrayController arrangedObjects ];
NSUInteger selectedIndex = [arrayController selectionIndex];
NSDictionary *d = selectedIndex == NSNotFound ? nil : [arrangedObjects objectAtIndex: selectedIndex];
return d;
}
- (void)setSelectedDictionary:(NSDictionary *)newDictionary
{
NSDictionary *oldDictionary = self.selectedDictionary;
if( newDictionary != oldDictionary )
{
/* the content of arrayController is bound to selection.value of some so far not mentioned
* NSDictionaryController.
* Not to be confused with the NSDictionaryController whose content is bound to our selectedDictionary.
**/
id controllerObjectProxy = [ dictionaryController selection ]; // _NSControllerObjectProxy
NSMutableArray *mutableProxy = [ controllerObjectProxy mutableArrayValueForKey: @"value"];
// shouldn't assume that the array orders are the same, so find it
NSUInteger sourceIndex = [mutableProxy indexOfObject: oldDictionary];
[mutableProxy replaceObjectAtIndex: sourceIndex withObject: newDictionary];
}
}
Your solution is definitely much more elegant than my clumsy attempts and works perfectly.
Thanks again for your help!
Kind regards,
Gerriet.
_______________________________________________
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