Re: Bindings with a custom view
Re: Bindings with a custom view
- Subject: Re: Bindings with a custom view
- From: Ricky Sharp <email@hidden>
- Date: Wed, 27 Jun 2007 17:59:50 -0500
On Jun 27, 2007, at 5:27 PM, Steve Israelson wrote:
I have made a custom view that can show a list of items in a grid
like view.
I also have a view of the same list in a table.
I have an NSArrayController bound to both views.
When I make a selection in the NSTableView, I correctly see that
same selection in my grid like view.
When I make a selection in my custom view, the NSTableView does NOT
mirror the selection.
It seems like the binding for the selected indexes is not working
for my custom view.
I can't see why though.
I looked at the KVC docs on ensuring compliance and I think I am
compliant.
Is there anything I am missing?
The relevant code is:
@interface PhotoGridView : NSView
{
NSIndexSet *selectedPhotoIndexes;
}
- (NSIndexSet *)selectedPhotoIndexes;
- (void)setSelectedPhotoIndexes:(NSIndexSet *)inSet;
@end
@implementation PhotoGridView
+ (void)initialize;
{
[self exposeBinding:@"selectedPhotoIndexes"];
}
- (NSIndexSet *)selectedPhotoIndexes;
{
return selectedPhotoIndexes;
}
- (void)setSelectedPhotoIndexes:(NSIndexSet *)inSet;
{
[selectedPhotoIndexes release];
selectedPhotoIndexes = [inSet copy];
[self setNeedsDisplay:YES];
}
@end
I'm going to assume that you've got some model that is bound to both
the table view and photo grid view (property of selectedPhotoIndexes).
Changes to your model should thus be reflected in both the table view
and custom view (i.e. model-initiated changes). I believe this
already works for you.
When you make a different selection in the table view, that's a "view-
initiated" change. The table view is doing the right thing and
updating the model which in turn drives a change to your custom view
(since it observes changes on your model).
What you now need to ensure is that such "view-initiated" changes
work with your custom view. You've got part of the code already there.
Beyond exposing the binding in +initialize, you'll want to look at
the implementing the following:
(1) accessors for observed object and observed object key paths. For
the attribute with name foo, I tend to have ivars like this:
id observedObjectForFoo;
NSString* observedKeyPathForFoo;
(2) provide an implementation of valueClassForBinding: which will
return [NSIndexSet class] if the given binding name is your custom
binding. Otherwise, call thru to super
(3) bind:toObject:withKeyPath:options:
(4) unbind:
(5) observeValueForKeyPath:ofObject:change:context:
(6) either setValue:forKey: or setNilValue:forKey: (comes in handy
when you're fed nil values for your attribute. You'll often want to
replace nil with some default value)
Then, in your custom view, look at all code that can change the
selection (most likely either mouseDown and/or keyDown methods you've
overridden). I like to create a common method I can call to do all
the bindings work. For example, for a custom control that uses a
custom "checked_II" binding:
- (void)triggerChangeForChecked_II:(int)newState
{
if ([self observedObjectForChecked_II] != nil)
{
[[self observedObjectForChecked_II]
setValue:[NSNumber numberWithInt:newState]
forKeyPath:[self observedKeyPathForChecked_II]];
}
NSAccessibilityPostNotification ([self cell],
NSAccessibilityValueChangedNotification);
}
Definitely check out the graphics and/or joystick bindings examples.
Links are found in this list's archives and are on mmalc's pages.
Virtually all of my bindings code came from the patterns used in the
joystick example.
___________________________________________________________
Ricky A. Sharp mailto:email@hidden
Instant Interactive(tm) http://www.instantinteractive.com
_______________________________________________
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