Pregunta

Ya he matado a un día sobre este tema y todavía tengo ni idea de cómo podría hacerse esto de una manera correcta.

Estoy usando NSOutlineView de jerarquía de imágenes del sistema de archivos. Para cada fila de la primera columna que necesito casilla pantalla, icono asociado y el nombre del archivo o directorio. Como no hay manera estándar de hacer esto, he subclases NSTextFieldCell usando ambos ejemplos SourceView y PhotoSearch, value vinculante en IB a la propiedad name de mi clase de elemento de árbol, aunque NSTreeController. Estoy usando anulación drawWithFrame:inView: pintar casilla de verificación e imagen, texto expedición dibujo a super. También estoy usando anulación trackMouse:inRect:ofView:untilMouseUp: a la interacción casilla mango.

Todo estaba bien hasta que me di cuenta de que una vez el botón I de ratón presione hacia abajo dentro de mi celda personalizado, objeto de celda se copia con copyWithZone: y este objeto temporal a continuación, se envía un mensaje trackMouse:inRect:ofView:untilMouseUp:, por lo que es imposible modificar estado de comprobación de la célula original que reside en la vista.

Dado que la cuestión objeto se trata de la unión, pensé que esto podría ser la respuesta, pero estoy totalmente de no entiendo cómo debo conectar todo este lío de funcionar como se espera. Intentado esto:

[[[treeView outlineTableColumn] dataCell] bind:@"state"
                                      toObject:treeController
                                   withKeyPath:@"selection.state"
                                       options:nil];

pero no tuvo éxito en absoluto. Parece que no estoy recibiendo la misma.

Que esta sea una manera completamente equivocada que he tomado? Podría sugerir una mejor alternativa ni a los enlaces de otras lecturas?


UPD 01/21/11 : También he intentado esto:

[[[treeView outlineTableColumn] dataCell] bind:@"state"
                                      toObject:treeController
                                   withKeyPath:@"arrangedObjects.state"
                                       options:nil];

pero mantuvo conseguir errores como "[<_NSControllerTreeProxy 0x ...> valueForUndefinedKey:]:. Esta clase no es valor de la clave de codificación compatible para el estado clave" y similar.

¿Fue útil?

Solución 2

Okay, I've managed to do what I needed by binding columns's value to arrangedObject's self (in IB) and overriding cell's setObjectValue: so that it looks like:

- (void) setObjectValue:(id)value
{
    if ([value isMemberOfClass:[MyNodeClass class]])
    {
        [super setObjectValue:[value name]];
        [self setIcon:[value icon]];
        [self setState:[value state]];
    }
    else
    {
        if (!value)
        {
            [self setIcon:nil];
            [self setState:NSOffState];
        }
        [super setObjectValue:value];
    }
}

Actual state change is performed within another class, connecting its method to cell's selector (in IB) which I call using

[NSApp sendAction:[self action] to:[self target] from:[self controlView]];

from cell's trackMouse:inRect:ofView:untilMouseUp:. This another class'es method looks like this:

- (IBAction) itemChecked:(id)sender
{
    MyNodeClass* node = [[sender itemAtRow:[sender clickedRow]] representedObject];
    if (node)
    {
        [node setState:[node state] == NSOnState ? NSOffState : NSOnState];
    }
}

Otros consejos

You bind a table (or outline) column's value, not an individual data cell's state. The data cell's object value is set to the current row/col's value then drawn so you don't have potentially thousands (or millions?) of cells created for no good reason.

Further, you want the tree or array controller's arrangedObjects, not its selection.

Bind the column's value to the tree controller's arrangedObjects as the controller key, and "state" as the model key path in IB; or @"arrangedObjects.state" in code as above.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top