[Résolu] Ajouter/supprimer des colonnes dans une TableView via les prefs.
Veillard
Membre
Bonjour,
Je cherche un moyen simple pour afficher ou non des colonnes dans une TableView selon les préférences de l'utilisateur.
Pensez-vous que "removeTableColumn:" et "addTableColumn:" soit le plus approprié pour gérer l'affichage des colonnes ou existe-t-il un moyen plus élégant ???
Merci à tous
Je cherche un moyen simple pour afficher ou non des colonnes dans une TableView selon les préférences de l'utilisateur.
Pensez-vous que "removeTableColumn:" et "addTableColumn:" soit le plus approprié pour gérer l'affichage des colonnes ou existe-t-il un moyen plus élégant ???
Merci à tous
Connectez-vous ou Inscrivez-vous pour répondre.
Réponses
Si la méthode tableColumnWithIdentifier: de NSTableView te renvoie nil pour une colonne dont tu passes son identifier en paramètre, c'est qu'elle n'est pas dans la tableView.
.
Par contre ça fonctionne à moitié. Quand je veux insérer une colonne, j'ai :
Le code est le suivant :
Tant que j'y suis, j'aimerais afficher à nouveau les colonnes à l'emplacement où elles étaient et non à la fin.
Bref, je cherche à faire une reconfiguration dynamique de ma tableView.
Ne vois-tu pas l'erreur ?
Dans le if, tu testes l'absence de la colonne @gaz (car tu testes à nil).
Mais, 2 lignes plus bas, dans le bloc du if, tu tentes d'insérer dans ta tableView, la colonne @gaz provenant de ta tableView... Puisque on sait que ça renvoie nil, tu fais un addTableColumn avec nil !
D'où le plantage.
.
Pour la réafficher, il faut la "réinsérer" dans la tableView (addTableColumn:).
Bien sûr, pendant que la tableColumn est retirée de ta table, il faut la conserver quelque part (pour la réinsérer plus tard).
Un exemple (sur une seule colonne dont l'identifier est @2, la tableView étant tb) :
La colonne est sauvegardé dans une variable d'instance tcsav déclarée comme :
[tt]NSTableColumn *tcsav;[/tt]
dans l'interface de ma classe contrôleur (celle qui réalise la masquage/affichage de la colonne).
A toi d'étoffer cette exemple pour gérer toutes les colonnes de ta tableView.
.
Donc, je rajoute dans l'interface une variable d'instance pour mémoriser la position de la colonne avant de la retirer :
[tt]int tcsavpos;[/tt]
et ensuite :
.
buildTableView
Je lis dans les préférences les colonnes affichées, je vérifie les cases cochées correspondantes aux colonnes à afficher ou à effacer, si elle n'est pas cochée, je la supprime de la TableVew sinon je la rajoute en tant que dernière colonne afin de garder l'ordre des colonnes defini par l'utilisateur..
addColumnFrom
Cette routine construit toute les caractéristique de la colonne "theColumn" avec les paramètres passé dans le NSDictionary.
- (void)buildTableView:(NSTableView *)aTableView
{
int i,j;
NSEnumerator *e;
id column;
NSArray *cbArray=[NSArray arrayWithObjects:plCBReference,plCBTitle,plCBOriginalTitle,plCBCategory,plCBScreenFormat,
plCBVideo,plCBMedia,plCBRuntime,plCBDate,plCBPurchaseDate,plCBAmountOfDVD,plCBAudience,
plCBDVDFormat,plCBPrice,plCBBorrower,plCBRating,plCBDirector,nil];
e = [[aTableView tableColumns] objectEnumerator];
while ( (column = [e nextObject]) ) {[aTableView removeTableColumn:column];}
NSDictionary *prefDictionary=[NSDictionary dictionaryWithDictionary:[prefs dictionaryForKey:@BNRPrefs]];
if (nil!=prefDictionary)
{
NSString *parametersPath=[[NSBundle mainBundle] pathForResource:@listTableViewColumn.plist ofType:nil];
NSArray *parametersArray=[NSArray arrayWithContentsOfFile:parametersPath];
if (nil!=parametersArray)
{
NSArray *anArray=[NSArray arrayWithArray:[prefDictionary objectForKey:@ColumnsForPrintList]];
if (nil!=anArray)
{
for (i=0;i!=[anArray count];i++)
{
for (j=0;j!=[cbArray count];j++)
{
if ([cbArray objectAtIndex:j] title] isEqualToString:[[anArray objectAtIndex:i] valueForKey:@"Title")
cbArray objectAtIndex:j] setState:NSOnState];<br /> }<br /> for (j=0;j!=[parametersArray count];j++)<br /> {<br /> NSMutableDictionary *aDictionary=[NSMutableDictionary dictionaryWithDictionary:[parametersArray objectAtIndex:j;
NSString *theTitle=[NSString stringWithString:[aDictionary valueForKey:@headerTitle]];
if ([theTitle isEqualToString:anArray objectAtIndex:i] valueForKey:@"Title")
{
if (nil!=[[anArray objectAtIndex:i] valueForKey:@currentSize])
[aDictionary setObject:[[anArray objectAtIndex:i] valueForKey:@currentSize] forKey:@currentSize];
else
[aDictionary setObject:[NSNumber numberWithInt:50] forKey:@currentSize];
[self addColumnFrom:aDictionary toTableView:aTableView];
}
}
}
}
}
}
}
- (void)addColumnFrom:(NSDictionary *)theColumn toTableView:(NSTableView *)aTableView
{
NSTableColumn *column = nil;
column = NSTableColumn alloc] initWithIdentifier:[theColumn valueForKey:@"identifier";
[column setEditable: theColumn valueForKey:@"editable"] boolValue;
if ([[theColumn valueForKey:@resizable] boolValue])
[column setResizingMask: NSTableColumnUserResizingMask];
else
[column setResizingMask: NSTableColumnNoResizing];
[column setWidth: theColumn valueForKey:@"currentSize"] intValue;
[column setMinWidth: theColumn valueForKey:@"minSize"] intValue;
[column setMaxWidth: theColumn valueForKey:@"maxSize"] intValue;
if (!theColumn valueForKey:@"headerTitle"] isEqualToString:[self readFromLocalize:@"Icone")
column headerCell] setStringValue:[theColumn valueForKey:@"headerTitle";
else
column headerCell] setStringValue:@" "];<br /> [[column dataCell] setAlignment:[[theColumn valueForKey:@"dataAlignment"] intValue;
column dataCell] setFont:[NSFont fontWithName:theFont size:fontSize;
column headerCell] setAlignment:[[theColumn valueForKey:@"headerAlignment"] intValue;
[aTableView addTableColumn: column];
[column release];
}
@Bru :
J'ai essayé. Ca fonctionne comme prévu pour supprimer la colonne mais quand je la rajoute, j'ai les messages d'erreur suivants :
@SpiderIncognito:
J'avais vu quelquechose se semblable là :
http://www.projectomega.org/article.php?lg=fr&php=oreilly_cocoa12&p=5
Je voulais savoir si il n'y avait pas plus simple.
Ca sent l'utilisation des bindings sur ta tableView, non ?
Dans ce cas, je ne vois pas trop quoi faire.
C'est pour cela que je hais les bindings, car ils enferment le programmeur dans un carcan.
.
Mais à la place, j'ai toujours :
avec le code de Bru qui fonctionne malgré tout (j'ai fait quelques tests).
L'insertion et la suppression fonctionnent. J'ai fait ceci :
J'ai supprimé les Retain/Release et mis un alloc initWithIdentifier à la place.
Par contre, l'en-tête s'appelle désormais "Field" et la largeur de la colonne a aussi changé. Je continue...
T'as vraiment pas compris le principe de masquage/affichage d'une colonne en la retirant/réinsérant dans sa tableView.
Je te donne le code que j'utilise (et qui fonctionne) dans mes applis.
Dans le .h de la classe contrôleur :
Dans le .m :
tb est l'outlet qui pointe sur la tableView.
L'emploi est simple, il suffit d'appeler la méthode pour afficher ou masquer la colonne dont l'identifiant est passé en paramètre :
[tt][self setColumn:@gaz visible:YES];[/tt] pour afficher la colonne gaz. Mettre NO pour la masquer.
A toi d'appeller cette méthode pour chaque préférence de chacune des colonnes (dans une boucle). Il faut utiliser cette boucle après le lancement de l'appli (dans le awakeFrmNib par exemple), puis ensuite à chaque fois que l'utilisateur modifie les préférences.
.
C'est vrai qu'à force de chercher de la doc sur le web, j'ai tendance à me mélanger les pinceaux.
Ton code fonctionne parfaitement, j'en ai profité pour me libérer de ce carcan de binding dans cette partie de mon appli. Comme tu peux le voir, j'ai pas mal de colonnes à gérer ce qui fait que j'ai un dans le cas où je veux ajouter une colonne alors qu'il manque la ou les précédentes. Je vais jouer sur l'"index".
[img]http://ch.veillard.free.fr/Image 1.png[/img]
Lorsque j'ai recopié mon code sur OC, je l'ai nettoyé et j'ai ajouté des commentaires.
Mais, j'ai fait sauter une ligne très importante :
[code]if (index>=tb tableColumns] count]) index=[[tb tableColumns] count]-1;[/code]<br />à mettre entre le [tt]if (index>=0) {[/tt] et le [tt][tb addTableColumn:[_cols objectAtIndex:index;[/tt]. 1000 excuses.
.
Tant mieux si ça marche, mais c'est pas à cause de moi...
J'ai dû chopé la grippe aviaire, et mon remède à base de boisson chaude fortement améliorée d'un liquide dont le degré d'alcool n'est pas en dessous de 40 font que ma cervelle patauge un peu...
Voici le bon code :
.
J'ai ajouter la posibilité d'afficher et masquer les colonnes. J'ai codé dans le même esprit que ce que tu montre Bru. Ca fonctionne mais quand je fait appel à le fonction d'affichage ou masquage cela ne fait rien jusqu'au relancement de l'appli!
Comment faire pour faire disparaà®tre une colonne après l'avoir supprimé avec[tt]removeTableColumn:[/tt]
La méthode [tt]- (void)setColumn:(NSString *)identifier visible:(BOOL)visible[/tt] que tu cites fonctionne correctement pour afficher/masquer dynamiquement les colonnes.
Je te joins un projet utilisant cette méthode. Le fait de cocher/décocher le bouton-option permet d'afficher/masquer en "live" la colonne correspondante.
.
[Fichier joint supprimé par l'administrateur]