La liaison unique NSCell à plusieurs valeurs
-
13-10-2019 - |
Question
Je l'ai déjà tué un jour à ce sujet et encore eu aucune idée sur la façon dont cela pourrait se faire de manière correcte.
J'utilise NSOutlineView
à la hiérarchie du système de fichiers d'affichage. Pour chaque ligne de la première colonne I besoin d'afficher case à cocher, l'icône associée et le nom du fichier ou du répertoire. Comme il n'y a aucun moyen standard de faire cela, je l'ai sous-classé NSTextFieldCell
utilisant à la fois des exemples SourceView et PhotoSearch, liant value
dans IB à la propriété de name
de ma classe d'élément d'arbre si NSTreeController
. J'utilise override drawWithFrame:inView:
pour peindre case et de l'image, le texte transmettant le dessin à super
. J'utilise aussi override trackMouse:inRect:ofView:untilMouseUp:
à l'interaction de case à cocher poignée.
Tout allait bien jusqu'à ce que je remarque qu'une fois que le bouton de la souris appuyez sur I vers le bas dans ma cellule personnalisée, objet cellulaire est copié avec copyWithZone:
et cet objet temporaire est alors envoyé un message trackMouse:inRect:ofView:untilMouseUp:
, ce qui rend impossible de modifier l'état de vérification de la cellule d'origine demeurant dans la vue.
Le sujet de la question est sur la liaison, je pensais que cela pourrait être la réponse, mais je ne comprends pas totalement comment dois-je connecter tout ce gâchis à fonctionner comme prévu. J'ai essayé ceci:
[[[treeView outlineTableColumn] dataCell] bind:@"state"
toObject:treeController
withKeyPath:@"selection.state"
options:nil];
mais n'a pas réussi du tout. On dirait que je ne suis pas l'obtenir.
Que ce soit une façon tout à fait tort, j'ai pris? Pourriez-vous suggérer une meilleure solution de rechange ou des liens pour aller plus loin?
UPD 21/01/11 : J'ai aussi essayé ceci:
[[[treeView outlineTableColumn] dataCell] bind:@"state"
toObject:treeController
withKeyPath:@"arrangedObjects.state"
options:nil];
mais continué à obtenir des erreurs comme « [<_NSControllerTreeProxy 0x ...> valueForUndefinedKey:]: cette classe n'est pas valeur de clé de codage conforme à l'état clé. » et similaires.
La solution 2
D'accord, j'ai réussi à faire ce que je avais besoin par la value
de colonnes se liant à la arrangedObject
de self
(en IB) et en remplaçant la setObjectValue:
de la cellule de sorte qu'il ressemble à:
- (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];
}
}
Changement state
réelle est effectuée dans une autre classe, reliant son procédé à la selector
de la cellule (en IB) que j'appel à l'aide
[NSApp sendAction:[self action] to:[self target] from:[self controlView]];
de la trackMouse:inRect:ofView:untilMouseUp:
de la cellule. Cette autre méthode de class'es ressemble à ceci:
- (IBAction) itemChecked:(id)sender
{
MyNodeClass* node = [[sender itemAtRow:[sender clickedRow]] representedObject];
if (node)
{
[node setState:[node state] == NSOnState ? NSOffState : NSOnState];
}
}
Autres conseils
Vous bind la valeur d'une colonne table (ou contour), pas d'état est une cellule de données individuelles. La valeur de l'objet de la cellule de données est définie sur la valeur actuelle de la ligne / colonne puis dessiné de sorte que vous n'avez pas potentiellement des milliers (ou millions?) De cellules créées pour aucune bonne raison.
De plus, vous voulez que le contrôleur de l'arbre ou un tableau arrangedObjects , et non sa sélection.
Bind de colonne la valeur de la de commande de l'arbre arrangedObjects comme la clé de commande, et "état" en tant que chemin de clé modèle IB; ou @ "arrangedObjects.state" dans le code comme ci-dessus.