PDA

View Full Version : Binding and Custom Controls




zedLondon
Jul 24, 2007, 10:29 AM
Well I've got much further along with myFirstCocoaApp™ and have now run into a bit of a problem with regards to a custom controller I'm working on and how to get it to display the correct info.

The data model set up is as follows

There are two array controllers A & B where B sets it's content array based on A.

I have a TableView displaying two of the properties of the objects in B (they're NSManagedObjects) and then have a number of text fields displaying all the properties.

What I'd like to do is replace the text fields with a single custom NSView subclass that displays all the property strings of the selected NSManagedObject with specific formatting.

Now at the moment what I'm thinking of doing is using


- (void)observeValueForKeyPath:(NSString *)keyPath
ofObject:(id) object
change:(NSDictionary *)change
context:(void *)context


and the addObserver: etc. to observe whenever NSArrayController B changes it's contents.

As far as I can make out I can only get the whole array from NSArrayController using -selectedObjects and reading that into an array.

So far so good. But how do I get it to change the selected object within that array based on the selection in the tableView?

I've got something working where my custom class gets the selected row number from the tableView and then looks that up in the array populated from B. But this requires an action to be triggered from a button. How can I get it to update whenever the user changes the selection in the table view?

Thanks in advance guys



Eraserhead
Jul 24, 2007, 12:17 PM
If the objects represented in the two arrayControllers are connected by a relationship, then you can bind the ContentSet of the second arrayController to the appropriate relationship of the selected object in the first.

If it's more complex than that you can use: -(void)tableViewSelectionDidChange:(NSNotification *)notification in the delegate of the tableView

zedLondon
Jul 25, 2007, 04:39 AM
If the objects represented in the two arrayControllers are connected by a relationship, then you can bind the ContentSet of the second arrayController to the appropriate relationship of the selected object in the first.

If it's more complex than that you can use: -(void)tableViewSelectionDidChange:(NSNotification *)notification in the delegate of the tableView

The two array controllers are already bound. B gets it's contentArray Dependent on the selection in A. The table is bound to arrayController B. So it doesn't have a delegate. The table only shows two of the properties of the objects in arrayController B and I want my custom control to show all of the properties of the object selected in the tableView. And I want to it to update whenever the selction in the table changes

I've looked at making my object complient to Bindings, but that seems like a lot of work, and was just wondering if anyone had an easier solution

Nutter
Jul 25, 2007, 05:04 AM
Why don't you just observe the array controller's "selectedObjects" property? If the table view is bound to that array controller, then its selection will always match that of the table.

Eraserhead
Jul 25, 2007, 05:35 AM
I want my custom control to show all of the properties of the object selected in the tableView. And I want to it to update whenever the selction in the table changes

Right, so tableViewSelectionDidChange is the one to use because Nutter is completely right when he says:
If the table view is bound to that array controller, then its selection will always match that of the table.

Personally in D&D Manager (http://www.erasersoft.com/main2/News/News.html) I use a mix of updating like this and bindings, which seems to work pretty well.

However I have tabs too so I call an updater method from -(void)tabView:(NSTabView *)tabView didSelectTabViewItem:(NSTabViewItem *)tabViewItem as well as tableViewSelectionDidChange.

zedLondon
Jul 25, 2007, 05:38 AM
Why don't you just observe the array controller's "selectedObjects" property? If the table view is bound to that array controller, then its selection will always match that of the table.

That's what i want to do, but doesn't the selectedObjects property retunt an array of the currently selected content array? Or am i misreading the documentation?

Does it return an array of objects selected in the tableView? If it does that would be brilliant!

Eraserhead
Jul 25, 2007, 05:41 AM
Does it return an array of objects selected in the tableView? If it does that would be brilliant!

You can get the array of objects selected with [arrayController selectedObjects], this certainly works with tableViewSelectionDidChange

zedLondon
Jul 25, 2007, 07:09 AM
You can get the array of objects selected with [arrayController selectedObjects], this certainly works with tableViewSelectionDidChange

Ok just to clear up my understanding. By selected objects, does that mean the content array of controllerB based on it's binding with A

so if A contains a list of languages and B contains a list of words then due to the binding if I select language1 from A then B's content array changes to be words from language1. Then tableview displays all these words. (well two properties of the words)

So if language1 is selected does [arrayControllerB selectedObjects] return the full contents of B at that time (all the words in language1) or does it return the single word that is selected in the tableView?

And if it's the latter and I use tableViewSelectionDidChange do I have to implement all the tableView Delegate methods?

PS Eraserhead the D&D manager looks cool! I'm actually building a tool to help building conlangs. The aim is to have a searchable dictionary for each language, a word generator (which i have working) where you can vary the parameters by language and a sound change applier (with sound change rules for each language). The idea being you can define wordlists for a parent language and then apply the sound changes to come up with correspondent words in different daughter languages.

Eraserhead
Jul 25, 2007, 07:23 AM
Ok just to clear up my understanding. By selected objects, does that mean the content array of controllerB based on it's binding with A

not really [arrayControllerA selectedObjects] returns the objects selected in arrayControllerA.


so if A contains a list of languages and B contains a list of words then due to the binding if I select language1 from A then B's content array changes to be words from language1. Then tableview displays all these words. (well two properties of the words)

FWIW You use the contentSet binding to link them.

So if language1 is selected does [arrayControllerB selectedObjects] return the full contents of B at that time (all the words in language1) or does it return the single word that is selected in the tableView?[/quote]
This returns the object selected in arrayControllerB's table, you use [arrayControllerB arrangedObjects] to get the full contents of arrayControllerB.

And if it's the latter and I use tableViewSelectionDidChange do I have to implement all the tableView Delegate methods?

No, just the ones you want.

PS Eraserhead the D&D manager looks cool!
Thanks :).

zedLondon
Jul 25, 2007, 07:27 AM
not really [arrayControllerA selectedObjects] returns the objects selected in arrayControllerA.



FWIW You use the contentSet binding to link them.

So if language1 is selected does [arrayControllerB selectedObjects] return the full contents of B at that time (all the words in language1) or does it return the single word that is selected in the tableView?
This returns the object selected in arrayControllerB's table, you use [arrayControllerB arrangedObjects] to get the full contents of arrayControllerB.

Fantastic! I'd misunderstood what the selectedObjects does.

Have the bindings working thanks, I must have used contentSet, just don't have it in front of me and can't always remember the names of all the functions/paramerters .. yet ;)

Thanks again!