macos - Enlace de un NSArrayController a un NSPopupButton y NSTextField
cocoa cocoa-bindings (1)
Lo que quiero lograr parece que debería ser bastante sencillo. He colocado un proyecto de muestra here .
Tengo un NSArrayController lleno de una variedad de NSDictionaries.
[[self controller] addObject:@{ @"name" : @"itemA", @"part" : @"partA" }];
[[self controller] addObject:@{ @"name" : @"itemB", @"part" : @"partB" }];
[[self controller] addObject:@{ @"name" : @"itemC", @"part" : @"partC" }];
Estoy rellenando un NSPopupButton con los elementos de esta matriz en función de la clave ''nombre''. Esto se logra fácilmente con los siguientes enlaces
Luego me gustaría rellenar un NSTextField con el texto en la tecla ''parte'' en base a la selección actual del botón NSPopupup. He configurado el siguiente enlace:
Solo con estos enlaces, el campo de texto muestra "parte C".
Sin embargo, si cambio el valor del NSPopupMenu, lo que muestra el campo de texto no cambia.
Pensé que esto sería simplemente una cuestión de configurar el enlace ''Objeto seleccionado'' en el NSPopupButton
pero eso no está funcionando. Terminé con el objeto proxy en mi menú por alguna razón extraña (explicando la razón por la cual sería un bono).
Entonces, ¿qué debo hacer para que esto funcione?
No use "Objeto seleccionado" en este caso. Enlace el enlace del "Índice seleccionado" de la ventana emergente a la clave del controlador de selectionIndex
de índice NSArrayController. Lo probé en su proyecto de muestra y funciona.
EDITAR:
Preguntó por qué es apropiado usar selectionIndex
sobre selectedObject
. Primero algunos antecedentes:
Al vincular un menú emergente, hay tres "Colecciones" virtuales que puede vincular: El contenido es el resumen "lista de cosas que deberían estar en el menú": siempre debe especificar el Contenido . Si no especifica Objetos de contenido ni Valores de contenido , la colección de valores vinculados al Contenido se utilizará como "objetos" y las cadenas devueltas por sus métodos de -description
se utilizarán como "valores". En otras palabras, los Valores de contenido son las cadenas que se muestran en la ventana emergente y los Objetos de contenido son las cosas a las que corresponden (que posiblemente no sean cadenas y que no tengan un método de -description
adecuado para generar el texto en el pop emergente). -arriba). Lo que es importante tener en cuenta aquí es que hay potencialmente tres ''arreglos virtuales'' diferentes en juego: el arreglo para Contenido , el arreglo para Objetos de Contenido (que puede ser diferente) y el arreglo para Valores de Contenido (que también puede ser diferente). Todos tendrán el mismo número de valores y, por lo general, los objetos de contenido y los valores de contenido serán funciones (en el sentido matemático) de los elementos correspondientes en la matriz de contenido .
Lo siguiente que es importante darse cuenta es que parte del NSArrayController
de NSArrayController
en la vida es hacer un seguimiento de la selección del usuario. Esto solo es ligeramente interesante (si es que lo hace) en el caso de una NSTableView
emergente, pero comienza a ser mucho más interesante en el caso de un NSTableView
. Internamente, NSArrayController
realiza un seguimiento de esto manteniendo un NSIndexSet
contiene los índices en la matriz de contenido que se seleccionan en un momento dado. A partir de ahí, el estado de selección se expone de varias formas diferentes para su conveniencia:
-
selectionIndexes
es como se describe: unNSIndexSet
contiene los índices de los elementos seleccionados en la matriz de contenido -
selectionIndex
es una opción conveniente para aplicaciones que no admiten la selección múltiple. Se puede considerar que es equivalente aarrayController.selectionIndexes.firstIndex
. -
selectedObject
también es útil en casos de selección única, y corresponde conceptualmente aContentObjectsArray[arrayController.selectionIndexes.firstIndex]
-
selection
devuelve un objeto especial (opaco al consumidor) que los corredores leen y registran en el objeto subyacente (u objetos en el caso de una selección múltiple) en la matriz de contenido del controlador de matriz. Existe para habilitar la edición de varios objetos a la vez en varios casos de selección y para proporcionar soporte para otros casos especiales. (Debería pensar en esta propiedad como de solo lectura; como su tipo es opaco para el consumidor, nunca podría crear un nuevo valor adecuado para escribir en ella. Es significativo hacer llamadas como:-[arrayController.selection setValue: myObject forKey: @"modelKey"]
, pero no tiene sentido hacer llamadas como-[arrayController setValue: myObject forKey: @"selection"]
Con esa comprensión de la propiedad de selection
, retrocedamos un paso y veamos por qué no es lo correcto en este caso. NSPopUpButton
trata de ser inteligente: le proporcionó una lista de cosas que deberían estar en el menú a través de los enlaces Contenido y Valores de contenido . Luego, además, le ha dicho que desea vincular su Objeto seleccionado a la propiedad de selection
del NSArrayController
. Probablemente esté pensando en esto como un enlace de "solo escritura", es decir, "Estimado mensaje emergente, tome la selección del usuario y colóquelo en el Controlador de array", pero el enlace es realmente bidireccional. Entonces, cuando se actualizan los enlaces, la ventana emergente primero llena el menú con todos los elementos de los enlaces de Valores de Contenido / Contenido , y luego dice: "Oh, usted dice que el valor en arrayController.selection
es mi Objeto Seleccionado . Eso es extraño - es no en la lista de elementos vinculados con mis enlaces de Valores de Contenido / Contenido . ¡Es mejor que lo agregue a la lista por ti! Lo haré llamando a -description
en ella, y metiendo esa cadena en el menú por ti ". Pero el objeto que obtiene de ese enlace de Objeto seleccionado es el objeto de selección opaco descrito anteriormente (y puede ver en el resultado que es de la clase _NSControllerObjectProxy
, una clase privada a AppKit como lo indica el subrayado principal).
En resumen, esa es la razón por la que vincular el enlace del Objeto seleccionado de su elemento emergente a la clave del controlador de selection
del controlador de arreglo es una acción incorrecta. Es triste decirlo, pero como estoy seguro de que has descubierto, la documentación de los enlaces de cacao solo comienza a rascar la superficie, así que no te sientas mal. He estado trabajando con Cocoa bindings casi a diario, en un proyecto a gran escala, desde hace varios años, y todavía siento que hay muchos casos de uso que aún no entiendo completamente.