2010-08-15 4 views
6

Bonjour J'essaye d'utiliser un NSPopUpButtonCell dans un NSTableView. Fondamentalement, lorsque vous sélectionnez un élément dans la fenêtre, je veux l'afficher dans la colonne/ligne de vue de la table. Quand un élément de la cellule contextuelle est pressé, je le stocke dans la source de données en utilisant "tableView: setObject: forTableColumn: row", puis quand la table demande des données que je récupère et définit l'état de la cellule popup dans "tableView: objectValueForTableColumn: rangée:". Veuillez trouver ci-joint mon code. Je suis complètement coincé en ce moment. J'espère que quelqu'un peut donner un sens à cela. Je vous remercie à l'avance.Utilisation de NSPopUpButtonCell avec NSTableView

C'est à l'intérieur du contrôleur:

//Create the table columns 
    NSTableColumn *nameColumn = [[NSTableColumn alloc] initWithIdentifier:LXDetailItemName]; 
    NSTableColumn *dataTypeColumn = [[NSTableColumn alloc] initWithIdentifier:LXDetailItemDataType]; 
    NSTableColumn *deviceColumn = [[NSTableColumn alloc] initWithIdentifier:LXDetailItemDevice]; 

    //Data type column drop down 
    NSPopUpButtonCell *dataTypeDropDownCell = [[NSPopUpButtonCell alloc] initTextCell:@"" pullsDown:YES]; 
    [dataTypeDropDownCell setBordered:NO]; 
    [dataTypeDropDownCell setEditable:YES]; 

    NSArray *dataTypeNames = [NSArray arrayWithObjects:@"NULL", @"String", @"Money", @"Date", @"Int", nil]; 
    [dataTypeDropDownCell addItemsWithTitles:dataTypeNames]; 
    [dataTypeColumn setDataCell:dataTypeDropDownCell]; 

    //Add the columns to the table 
    [tableView addTableColumn:nameColumn]; 
    [tableView addTableColumn:dataTypeColumn]; 
    [tableView addTableColumn:deviceColumn]; 
    enter code here 

C'est à l'intérieur de la classe source de données/délégué.

enter code here 

@implementation LXTestDataSource 

- (id)init 
{ 
self = [super init]; 

if (self) 
{ 
    tableContents = [[NSMutableArray alloc] init]; 

    //Setup test data 
    NSMutableArray *keys = [NSMutableArray arrayWithObjects:LXDetailItemName, LXDetailItemDataType, LXDetailItemDevice, nil]; 
    NSMutableArray *objects = [NSMutableArray arrayWithObjects:@"one", @"NULL", @"NULL", nil]; 

    for (int i = 0; i < 4; i++) 
    { 
    NSMutableDictionary *dictionary = [[NSMutableDictionary alloc] initWithObjects:objects forKeys:keys]; 
    [tableContents addObject:dictionary]; 
    [dictionary release]; 
    } 
} 

return self; 
} 

- (NSInteger)numberOfRowsInTableView:(NSTableView *)aTableView 
{ 
return [tableContents count]; 
} 


- (id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)aTableColumn row:(NSInteger)rowIndex 
{ 
if ([[aTableColumn identifier] isEqualToString:LXDetailItemDataType]) 
{ 
    NSMutableDictionary *rowDictionary = [tableContents objectAtIndex:rowIndex]; 
    NSString *title = [rowDictionary objectForKey:LXDetailItemDataType]; 

    NSLog(@"objectValueForTableColumn: %@", title); //DEBUG 

    return [NSNumber numberWithInt:[[aTableColumn dataCell] indexOfItemWithTitle:title]]; 
} 
else if ([[aTableColumn identifier] isEqualToString:LXDetailItemDevice]) 
{ 
    NSMutableDictionary *rowDictionary = [tableContents objectAtIndex:rowIndex]; 
    NSString *title = [rowDictionary objectForKey:LXDetailItemDevice]; 

    NSLog(@"objectValueForTableColumn: %@", title); //DEBUG 

    return [NSNumber numberWithInt:[[aTableColumn dataCell] indexOfItemWithTitle:title]]; 
} 
else 
{ 
    NSMutableDictionary *rowDictionary = [tableContents objectAtIndex:rowIndex]; 
    return [rowDictionary objectForKey:[aTableColumn identifier]]; 
} 
} 


- (void)tableView:(NSTableView *)aTableView setObjectValue:(id)anObject forTableColumn:(NSTableColumn *)aTableColumn row:(NSInteger)rowIndex 
{ 
if ([[aTableColumn identifier] isEqualToString:LXDetailItemDataType]) 
{ 
    NSMenuItem *menuItem = [[aTableColumn dataCell] itemAtIndex:[anObject integerValue]]; 

    NSMutableDictionary *rowDictionary = [tableContents objectAtIndex:rowIndex]; 

    NSLog(@"%@", [menuItem title]); //DEBUG 

    //Update the object value at the column index 
    [rowDictionary setObject:[menuItem title] forKey:LXDetailItemDataType]; 
} 
else if ([[aTableColumn identifier] isEqualToString:LXDetailItemDevice]) 
{ 
    NSMenuItem *menuItem = [[aTableColumn dataCell] itemAtIndex:[anObject integerValue]]; 

    NSMutableDictionary *rowDictionary = [tableContents objectAtIndex:rowIndex]; 

    NSLog(@"%@", [menuItem title]); //DEBUG 

    //Update the object value at the column index 
    [rowDictionary setObject:[menuItem title] forKey:LXDetailItemDevice]; 
} 
else 
{ 
    //Get the row 
    NSMutableDictionary *rowDictionary = [tableContents objectAtIndex:rowIndex]; 

    //Update the object value at the column index 
    [rowDictionary setObject:anObject forKey:[aTableColumn identifier]]; 
} 
} 

@end 
+0

// données de test Configuration \ n NSDictionary * dictionnaire = @ {LXDetailItemName: @ "un", LXDetailItemDataType: @ "NULL", LXDetailItemDevice: @ "NULL"}; \ n for (int i = 0; i <4; i ++) {\ n [tableContents addObject: dictionnaire]; \ n } \ n – geowar

Répondre

3

Je pense que je l'ai compris. J'utilise la méthode "setTitle:" de la cellule pop-up pour mettre à jour le texte de la cellule après avoir cliqué sur l'élément de menu. Voici la méthode delegate de vue de table que j'ai utilisée.

- (void)tableView:(NSTableView *)aTableView willDisplayCell:(id)aCell forTableColumn:(NSTableColumn *)aTableColumn row:(NSInteger)rowIndex 
{ 
    if ([[aTableColumn identifier] isEqualToString:LXDetailItemDataType]) 
    { 
     NSMutableDictionary *rowDictionary = [tableContents objectAtIndex:rowIndex]; 
     NSString *title = [rowDictionary objectForKey:LXDetailItemDataType]; 

     [aCell setTitle:title]; 
    } 
    else if ([[aTableColumn identifier] isEqualToString:LXDetailItemDevice]) 
    { 
     NSMutableDictionary *rowDictionary = [tableContents objectAtIndex:rowIndex]; 
     NSString *title = [rowDictionary objectForKey:LXDetailItemDevice]; 

     [aCell setTitle:title]; 
    } 
} 
+0

Ce que je ne comprends pas, c'est que si le code ci-dessus fonctionne, pourquoi dois-je retourner quoi que ce soit pour la (les) cellule (s) contextuelle (s) dans la méthode de la source de données "tableView: objectValueForTableColumn: row:". Je ne peux rien retourner pour la cellule popup de cette méthode et cela fonctionnerait toujours. Des commentaires? – David

+0

Je suis tombé sur ce même problème 6 ans plus tard en utilisant Swift 3. Il semble que le réglage de l'élément de menu sur 'NSPopupButtonCell' dans' objectValueFor: tableColumn' ne persiste pas, mais le mettre dans 'willDisplayCell' fonctionne. Curieusement, les champs de texte et les cases à cocher ** fonctionnent ** très bien sans willDisplayCell. –

2

Je pense que tout ce que vous devez faire après le réglage de la valeur tableView:setObjectValue:forTableColumn:row: est d'appeler reloadData sur la vue de la table pour le forcer à se mettre à jour avec les modifications apportées au modèle de données. NSPopUpButtonCell utilise l'index de l'élément comme valeur d'objet, de sorte qu'une partie des choses devrait fonctionner correctement sans ce code dans la méthode déléguée willDisplayCell. En outre, je recommanderais d'utiliser la propriété representedObject d'un élément de menu pour indiquer la partie éléments plutôt que le titre. Les titres d'éléments de menu peuvent potentiellement être localisés, et l'utilisation de titres pour stocker des valeurs de données est très susceptible de se briser.

+0

J'ai essayé d'appeler reloadData après avoir défini la valeur de l'objet comme vous l'avez mentionné et le NSPopUpButtonCell ne se met pas à jour lui-même. C'est un bon point sur le representatedObject, je vais l'utiliser. Merci. – David