macos cocoa cocoa-bindings nsarraycontroller

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: un NSIndexSet 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 a arrayController.selectionIndexes.firstIndex .
  • selectedObject también es útil en casos de selección única, y corresponde conceptualmente a ContentObjectsArray[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.