When binding to Collection<T>, how to make each view item bound to wrapper object of T - collectionviewsource

I have a collection (IList) bind to ListView, now, by default Foo is bind to item in the list view, but I want to bind wrapper of (Foo) = Goo to each list view item.
IList is returned from the system API which returns virtualized list of item of Foo, but in my list view item, i want to bind custom object which is a wrapper of Foo=Goo.
One solution is to create list of Goo from list of Foo, unfortunately that is not possible in this case, any converter approach available in this case.
Any help is appreciated.

Try using inheritance such that Foo is the base class and Goo is a subclass that extends Foo.

Related

Syntax of Model Key Path - Bindings xcode 5.1.1

Hey I am new to mac development and I want to use bindings (xcode 5.1.1).
I want to set the Title of a radio button dynamically by an entry of an array controller. I am looking for something like a syntax description how I can perform it.
e.g. something like value1 WHERE value2="bla"
If I trying to search at google I always find solutions which did it programmatically.
Is there anywhere some examples which show me the syntax I can use in this field?
The picture below should you show what I mean.
Answering the question as clarified in the comments…
First, bindings is not always the right technology. It can simplify some things, but it can't do everything and even for some of the things that it can do, it doesn't necessarily make them simpler.
Radio buttons are often organized in an NSMatrix. In that case, you can bind the matrix bindings to track the selection. There are three content-related bindings for a matrix, which can be kind of confusing. The "content" binding is the base. In some cases, it's sufficient. However, if there's a distinction between the object being bound and the value that should be shown by the cells of the matrix, then you can bind the "contentValues" binding to be a subpath of the content binding. That is, it needs to be the same as the content binding with possibly additional elements added to the end of the model key path.
Furthermore, if you want the selected object to be distinct from the content object, you can bind "contentObjects" to a subpath of the content binding.
For example, there may be an array controller whose content is a bunch of Person objects. The matrix content binding might be bound to that array controller's arrangedObjects. If you leave it like that, the cells of the matrix will be populated from the description of each Person object. However, you could bind the matrix's contentValues to the array controller, arrangedObjects, model key path fullName. Then, the matrix cells will be populated with the full name of each Person object.
If you then bind the matrix's selectedObject binding to a property on your window controller, that property will be set to the selected Person object each time the matrix selection changes. If you would prefer, you could bind the matrix's contentObjects binding to the array controller, arrangedObjects, model key path uniqueID. In that case, the window controller property would not be set to the selected Person object itself, but to its uniqueID property.
Alternatively, you could bind the matrix's selectedIndex binding to a controller property. If you use the window controller, then that just directly sets a property on the window controller to indicate the index of the matrix's selection. Or you could bind it to the array controller's selectedIndex property, in which case the selection is "stored" in the array controller.
You need a keypath that takes no parameter as described in the key-value coding (KVC) reference.
By binding to an array controller's selection, if the selection collection is one object with a property or method "value1," then the binding runtime is calling the method valueForKeyPath:#"value1".
The NSObject protocol has performSelector:withObject, but there is nothing like valueForKeyPath:withObject in the KVC protocol or the NSKeyValueBindingCreation protocol
That said, registering dependent keypaths can provide some equivalent behavior...
+ (NSSet*) keyPathsForValuesAffectingValue1
{
return [NSSet setWithObjects:#"value2",nil];
}
... and that would ensure that any time value2 changes, the binding to value1 is re-evaluated.

Why add/remove method was called automatically when NSArrayController binds to an array?

I'm trying to understand how NSArrayController works...
When I create an NSMutableArray "employeeArray" to hold "Person" object.
I use NSArrayController in GUI and bind with the "employeeArray".
I add two buttons for adding and removing "Person" objects in "employeeArray". Both buttons are binded with the received action "add:" and "remove:" of NSArrayController.
Inorder to do something else when adding/removing "Person" objects in "employeeArray", I add two methods:
(void)insertObject:(Person *)p inEmployeeArrayAtIndex:(NSUInteger)index;
(void)removeObjectFromEmployeeArrayAtIndex:(NSUInteger)index;
Question:
I didn't do anything(write any code) to let NSArrayController know the two methods above, why they are called automatically when I click the add/remove button? What happened?
What add/remove method does NSArrayController use?
Does NSArrayController smart enough to recognized those methods? What if I modified the method names randomly, will it be called correctly?
I think I finally understand:
By following "Key-Value Coding Accessor Methods Patterns". NSArrayController is smart enough to recognize the "insert" "remove" methods automatically.
If you alter the method name without following the accessor pattern. It will not work.

Core Data Search [Cocoa Bindings]

I have a project that has a Entity called : Verse. The Verse (entity) has a Attribute called : VerseContent (String). I have it successfully linked to a Table View and I have a Search Bar on the top. The Table View is binded to VersesArrayController (NSArrayController which has it's Managed Object Context binded to my App Delegate's Managed Object Context). I don't really want to write any code and I recall that this is possible through Cocoa Bindings. How should I bind this Search Bar and my NSTableView together?
Thanks~
Bind the NSSearchField Predicate to VersesArrayController, and leave Model Key Path empty. You'll find Predicate under "Search" in the bindings tab. Then set the Predicate Format to:
verseContent contains $value
Checking Validates Immediately will give you live searching, leaving it unchecked requires you to hit Enter (or some other form of 'Submit').

What's the Difference between "Content Values" and "Content Objects"

I'm exploring bindings right now, and have an NSPopUpButton -
It presents me a number of options for bindings under Value Selection - Content, Content Objects, Content Values, and then Selected Object, Selected Value, and Selected Tag. Could someone please explain the difference between these?
Those are explained in the Cocoa Bindings Reference for NSPopUpButton, although that reference is not quite clear.
Content is an array controller that provides elements to the popup button. The array controller should be bound to an array. In order to determine how each element in the array is shown in the popup button, -description is sent to each object in the array.
You may customise this in two ways:
If you want the Selected Object binding to provide an object distinct from the array elements managed by the array controller to which Content was bound, you can bind Content Objects to another array controller. It could also be the same array controller but with a different key path;
If you want the popup button options to be something different than the description of each element in the array managed by the array controller to which Content was bound, you can bind Content Values to another array controller that manages an array whose elements contain the popup options. It could also be the same array controller but with a different key path.
A simple example: suppose you have the following class:
#interface Customer : NSObject
#property (copy) NSString *name;
#property (copy) NSString *phoneNumber;
#end
and you haven’t overridden the -description method. In this case, -descriptionis useless and the name property would be a good choice for the popup options. You’d bind:
Content to an array controller that manages an array of Customer instances, controller key arrangedObjects;
Content Values to the same array controller, controller key arrangedObjects, model keypath name.
You can then bind Selected Object to something else, for example a property in your application delegate or window controller. Cocoa bindings would then assign the selected Customer instance to that property.
Now suppose you are not interested in the whole Customer object that’s been selected, but only its phone number. In this case, you can bind Content Objects to the same array controller, controller key arrangedObjects, model keypath phoneNumber. When a popup option is selected, Cocoa bindings will set phoneNumber instead of an entire Customer instance. In summary: if you don’t bind Content Objects, Selected Object represents the original object in the array. If you bind Content Objects, then Selected Object can be something different.
You’d bind Selected Value if you were not interested in the original objects (or the content objects), but the actual strings shown in the popup options according to the Content Values bindings.
Quick recipe for providing data to the popup button:
Bind Content if you have objects (not only strings) that represent the popup options;
Bind Content Values if the options that are shown to the user cannot be obtained via Content by sending -description to the array elements;
Bind Content Objects if you want Selected Object to return something different from the array elements from Content.
Quick recipe for obtaining the current selection in a popup button:
Bind Selected Object if you want to know the full object (either from Content or Content Objects) representing the current popup selection;
Bind Selected Value if you only want the string that’s currently selected in the popup.
And lastly, you’d use Selected Tag if the popup options are actually taken from a menu whose items have a tag set.
#Object refers to any KVC-compliant object. #ObjectValue refers to the key path used to get the value from that object.
So, for your pop-up binding, ContentObjects would be bound to, say, an NSArrayController's arrangedObjects. Say this refers to an array of dictionaries or managed objects. You can't meaningfully present a dictionary in a pop-up (you get the start of the description output, e.g <NSCFDictionary... or similar), so this is where the contentValues binding comes in. This would be something like your NSArrayController's arrangedObjects.name, where name is a key from your dictionary or managed object.
I hope this helps, I struggled with the same concept myself when I started with bindings.

How do I use an NSFormatter subclass with an NSPopUpButton

I want to use an NSFormatter subclass to format the contents of an NSPopUpButton I'm using to display a list of choices.
Basically I have an NSArray of MyObjects which is bound to the NSPopUpButton via the Content Values binding and I want to display something in the pop up menu other than what is returned by -description. I don't really want to use a transformer because then I have to create an entirely new array and transform each object into a string before adding it to the new array.
Using setFormatter: on the NSPopUpButton itself via either IB or code doesn't work, I suspect because only the formatter for the individual cell is applied to the items in the list.
Is there an easy way to set a formatter for all the cells of the NSPopUpButton? Basically I want to just be able to set it once and forget about it.
Typically you'd bind your popup button to an array controller that contains custom model objects (through the content binding), and use the content values binding to specify a keypath on those object with the string you want to use as the title.
From what I understand, you have an array of plain strings you want to use as the data source, only you want to display a different string for the title, right?
I'm not sure why making a data transformer wouldn't work if set up like the above-- or maybe I'm misunderstanding something? You'd have one binding to the actual string, and another binding to the string using a transformer, but both of them would be using the same array controller. Your other options are creating a model class to wrap around the strings and provide a title property, or creating a category on NSString that returns your title to use as the display value binding. In all of these cases you can create your own NSFormatter in code and use it to return the correct string title.

Resources