2010-08-15 5 views
6

Ciao Sto cercando di utilizzare un NSPopUpButtonCell all'interno di NSTableView. Fondamentalmente quando si seleziona un elemento nel pop up lo voglio visualizzato nella colonna/riga della vista tabella. Quando viene premuto un elemento nella cella popup, lo memorizzo all'interno dell'origine dati utilizzando "tableView: setObject: forTableColumn: row", quindi quando la tabella richiede i dati che recupero e imposta lo stato della cella popup in "tableView: objectValueForTableColumn: riga:". Si prega di trovare il mio codice allegato. Sono completamente bloccato in questo momento. Spero che qualcuno possa dare un senso a questo. Grazie in anticipo.Utilizzo di NSPopUpButtonCell con NSTableView

questo è all'interno del regolatore:

//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 

Questo è all'interno della classe origine dati/delegato.

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

// Setup prova data \ n NSDictionary * dizionario = @ {LXDetailItemName: @ "uno", LXDetailItemDataType: @ "NULL", LXDetailItemDevice: @ "NULL"}; \ n for (int i = 0; i <4; i ++) {\ n [tableContents addObject: dictionary]; \ n } \ n – geowar

risposta

3

credo di aver capito. Io uso il metodo "setTitle:" della cella pop-up per aggiornare il testo della cella dopo aver fatto clic sulla voce di menu. Ecco il metodo delegate della vista tabella che ho usato.

- (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

Quello che non capisco è se il codice sopra funziona allora perché devo restituire qualcosa per le celle popup? nel metodo dell'origine dati "tableView: objectValueForTableColumn: row:". Non posso restituire nulla per la cella popup in questo metodo e funzionerebbe ancora. Qualche commento? – David

+0

Mi sono imbattuto in questo stesso problema più di 6 anni dopo usando Swift 3. Sembra che l'impostazione della voce di menu su 'NSPopupButtonCell' all'interno di' objectValueFor: tableColumn' non permanga, ma il suo inserimento in 'willDisplayCell' funziona. Stranamente, i campi di testo e le caselle di controllo ** funzionano ** senza 'willDisplayCell'. –

2

penso che tutto ciò che dovrebbe essere necessario fare dopo aver impostato il valore in tableView:setObjectValue:forTableColumn:row: è chiamare reloadData sulla vista tabella per costringerlo a aggiornarsi con le modifiche apportate al modello di dati. NSPopUpButtonCell utilizza l'indice oggetto come valore dell'oggetto, in modo che una parte delle cose funzioni correttamente senza quel codice nel metodo delegato willDisplayCell.

Come parte, vorrei raccomandare l'utilizzo della proprietà representedObject di una voce di menu per indicare la parte degli articoli anziché il titolo. I titoli delle voci di menu possono essere potenzialmente localizzati e l'utilizzo di titoli per memorizzare i valori dei dati è molto suscettibile alla rottura.

+0

Ho provato a chiamare reloadData dopo aver impostato il valore dell'oggetto come menzionato e NSPopUpButtonCell non si aggiorna da solo. Questo è un buon punto su representObject, lo userò. Grazie. – David