7

Me pregunto cómo se podría implementar una vista de esquema como el que Xcode 3 está utilizando para la configuración de generación:Ejecución NSOutlineView/NSTableView con células de diferentes tipos de datos (y) por fila

alt text http://img812.imageshack.us/img812/9467/xcodeoutlineview.png

Cuando utilizando un NSOutlineView/NSTableView con enlaces y un NSTreeController/NSArrayController, las columnas de la vista obtienen enlaces asignados a, no las celdas individuales, por razones obvias. Si cada fila en una columna usa la misma celda, entonces es pan comido. Sin embargo, si cada fila (potencialmente) utiliza su propio tipo de celda (y con eso, potencialmente, su propia colección de enlaces), entonces las cosas se ponen de moda.

Al observar la captura de pantalla, se puede ver claramente que la celda del campo de texto solo necesita una sola encuadernación para "valor". Si bien la pila de botón emergente necesita al menos una para "contenido", uno para "contentValues ​​" y por último pero no por ello menos uno vinculantes para "selectedIndex/selectedObject/SelectedValue". Y la celda de casilla de verificación necesita un enlace para "valor" y (probablemente) uno para "título".

¿Cómo se puede lograr esto con un código tan limpio (y poco) como sea posible?
(O como uno podría preguntar:¿Cómo Apple ha hecho?)

...

Aquí es lo que he intentado yo mismo hasta el momento:
que proporcionan las células apropiadas (copiado) a través de [outlineView: dataCellForTableColumn: item:] y vincúlelos a los modelos de datos individuales (del [elemento representadoObjeto]). Sé la cantidad exacta de datos (< 500 filas) que se muestran en la vista de esquema, por lo que tener una celda por fila no debería ser un problema de memoria, ¿no? Obtuve los datos para mostrarse correctamente a través de enlaces (yay!) Sin embargo, no puedo cambiar ninguno de sus valores. O_o Aparentemente, el cambio de valor simplemente nunca pasa al modelo de datos. ¿Hay algo más que un simple [checkboxCell bind: @ "value" toObject: rowModel withKeyPath: @ "value" options: nil]? (Ya que esto parece suficiente para conseguir valores, pero no para establecer en consecuencia.)

no pude encontrar ninguna información sobre este tema. Mucha información y sugerencias para usar celdas personalizadas por columna, pero ninguna para usarlas "por fila". :(
Esto sería una gran cosa para un tutorial de Cocoa, ¿no?;)

+0

También está NSDictionaryController. No sé qué tan lejos te llevará hacia esto, pero echa un vistazo. –

+0

@Mike No es tanto un problema del controlador, sino una de las vistas de tabla que maneja sus celdas. Pero gracias de todos modos :) – Regexident

+0

casi 5 años después y esta fue la única información que pude encontrar sobre la mezcla de enlaces con fuentes de datos en una tabla con diferentes celdas, "Esto sería una gran cosa para un tutorial de Cocoa, ¿no?" ¡diablos, sí! – rraallvv

Respuesta

3

La celda de datos de una columna no se copia. La celda está configurada para el valor correcto para la columna en cada fila y dibujada en su lugar apropiado. Un buen lugar para enganchar es en el método NSTableColumn -dataCellForRow:. En una subclase personalizada, puede anular este método y pasar su -dataCell para el funcionamiento normal o algún tipo de celda alternativa.

Tuve la oportunidad de tener una columna de casilla de verificación que representa "incluir" en una vista de esquema que solo apareció para niños (elementos no de raíz). No se pudieron excluir los elementos raíz, solo sus hijos, por lo que solo tenía sentido mostrar la casilla de verificación para los elementos que no son raíz.

Creé una subclase de NSTableColumn personalizada que tomó un delegado (mi controlador de origen de datos) y comprobé para ver si respondía al selector -deadCellColumn: shouldShowDeadCellForRow :. Si lo hizo, llamé a ese método (que se implementó en mi controlador de origen de datos) para preguntarle si debería mostrar una "celda muerta" (una subclase NSCell básica que no atrae nada) y la cambié de acuerdo con la respuesta. Si el delegado no respondió al selector, la columna de la tabla devuelve su normal -dataCell.

La celda personalizada (a la que llamé "DeadCell") era necesaria aquí porque quería asegurarme de que no se dibujara nada y de que no hubiera nada editable. No estoy seguro de que sea estrictamente necesario, pero lo hice de todos modos. Esto no es muy útil en su caso, pero quería decirlo de todos modos para que esté completo.

Su situación es un poco más complicada, especialmente porque las vinculaciones están involucradas (y los diferentes tipos de celdas de datos pueden tener diferentes enlaces por su valor - las ventanas emergentes pueden ser especialmente desafiantes). En mi caso, evité enlaces para el mecanismo de fuente de datos probado y verdadero. Simplificó las cosas en gran medida. :-) Para su caso, es bastante fácil intercambiar tipos de celda utilizando métodos de fuente de datos.

+0

Oh mi ... Supongo que tendré que unificar mi entrada de datos (utilizando ComboBoxCells para acceder fácilmente a los valores de la plantilla) y usar NSFormatters para garantizar la entrada adecuada para el tipo de valor de cada elemento. No es bonita, pero la característica que requiere dicha vista de tabla simplemente no es lo suficientemente grande/importante como para invertir un código de back-end tan grande y probablemente un hackeo. Sin embargo, es una lástima que tales cosas sean un desastre para trabajar. – Regexident

+0

No hay hackers involucrados en absoluto. Es todo uso válido del mecanismo de control/célula. Además, las uniones de cacao se dirigen más hacia el lado del desarrollo de aplicaciones rápidas, lo que solo elimina el código para los casos más generalizados. Si quieres hacer cosas especiales, debes usar el código. En muchas situaciones, puede mezclar los dos (enlaces y fuente de datos). En esta situación, si todos los tipos de su celda comparten los mismos enlaces, solo necesita su columna personalizada y todo lo demás debería "funcionar". –

+0

Sí, pero ** no ** comparten los mismos enlaces :( Y la función será una nerd de todos modos, con una base de usuarios muy limitada, por lo que simplemente no vale la pena un esfuerzo excesivo mientras se demora la publicación del producto. ("Great developer ship", ¿verdad?;) Pero gracias por la solución. Estoy seguro de que lo usaré no muy lejos. – Regexident

Cuestiones relacionadas