NSTableView, dataSource et NSTabView

thomzz

Membre confirmé
18 Mars 2003
77
0
Visiter le site
Salut à tous,

J'ai quelque problèmes avec les sources de données des tables.
J'aimerai faire une application qui, quand on clique sur un bouton, ajoute un NSTabItem dans un NSTabView avec, à l'intérieur, une nouvelle table. Le pb c'est que n'arrive pas à "connecter" une source de données cette table (que doit être la source de données ?).

Si quelqu'un peut m'aider.

Merci
 
J'ai juste commencé à plonger dans le même sujet. Tu peux trouver des choses très intéressantes sur le projet omega et o'reilly, en particulier ici

Regarde en particulier les tutoriels sur les préférences et sur le carnet d'adresses : ça m'a permis de comprendre un minimum la gestion tablewiew/datasource.

Télécharge les pdf et les projets, teste et modifie. J'ai une ou deux autres références, mais pas ici. Je t'en ferais part plus tard.

Je commence juste, donc je préfère te donner des références que te faire part de mes avis qui sont très peu informés
laugh.gif
.


PS. Si tu sais te débrouiller avec les tables et que ton pb, c'est uniquement les tables dans les tables, là c'est plutôt moi qui aurais besoin de ton aide
laugh.gif

 
Moi, non plus
laugh.gif

Mais, hier, j'ai eu enfin l'occasion de passer 2 heures dessus et j'ai pu me créer 2 tables avec les datasource (NSarray) qui apparemment semblent prêtes à se mettre à jour quand il faut (c'était ça mon premier problème : je n'avais pas bien pigé le object..; et le setobject...). Il me reste à rajouter 2-3 trucs (dont le reload) pour vérifier que ça marche, même si c'est pas malin, c'est à dire que les modifs par l'utilisateur dans une des tables sont prises en compte et peuvent éventuellement entraîne des modifs dans l'autre.

(Pas encore à travers des delegate ou des notifications, ça on verra après).
 
Pour bien comprendre la relation NSTableViexw et les data sources il faut se souvenir de ceci :

Une TableView a besoin d'une source de données pour retrouver ces objets.

Cette source de données doit implémenter au moins 3 methodes du protocole NSTableDtaSource. Ces methodes sont appelées automatiquement par la NStableView qu'elle alimente pour :
- Retrouver un élément de ligne i et de colonne j
- de le modifier
- de savoir combien la source contient d'éléments.

Voyer en détail ces méthodes ici :
http://developer.apple.com/techpubs/macosx/Cocoa/Reference/ApplicationKit/ObjC_classic/Protocols/NSTableDataSource.html#BCICFCDE

La data source on peut la définir de plusieurs façons. ça peut être un fichier, une table, etc. L'essentiel c'est qu'on puisse implémenter les méthodes que j'ai décrit.
En général (pour des raisons de commodité), on fait tout pour avoir une data source qui soit une NSMutableDictionnary ou NSDictionnary car les méthodes du protocoles y sont quasiment implémentées.
N'oubliez pas que l'on peut ajouter à la data source d'autres méthodes. Par exemple le tri par une colonne, la suppression, d'une ligne, etc. Ne pas oublier qu'en fait le reload de la NStableView a pour conséquence d'appeler la méthode de recherche d'une ligne autant de fois que la data source a d'elements.

J'espère que cela vous eclairera.

Il y a un exemple ici :

http://developer.apple.com/techpubs/macosx/Cocoa/TasksAndConcepts/ProgrammingTopics/TableView/Tasks/UsingTableDataSource.html#//apple_ref/doc/uid/20000117

 
Effectivement, les dictionnaires ont l'air très propres pour plein de choses. Mais je commence avec des NSarray pour y aller progressivement et éviter de m'embrouiller entre la compréhension de la liaison tableview/datasource et celle des dictionnaires. Dès que j'ai au moins un schéma avec les array qui me convient, je passe aux dictionnaires.

Là, il faudra que je vois à quel endroit placer des messages de recalcul lorsque les données sont modifées pour qu'ils soient le plus efficaces possible : dans le setObject ? avec un delegate ou une notification spécifique ? ailleurs ?

(typiquement, dans les trucs que je veux faire, la modification d'une cellule de la table par l'utilisateur impose de recalculer le contenu de cellules d'autres tables).
 
Et comment on fait pour que les datasource ne soit pas le Controller ?
Car en suivant le tutoriel O'Reilly/ProjectOmega, dans Interface Builder on relie tableView à l'outlet du Controller.
 
Il ne faut pas confondre Controller et data source. Généralement quand on a une interface graphique, on l'associe à un Controller. En effet les objets de l'interface sont décrits dans le controller sous forme d'outlets ainsi que les actions executées par une target (un bouton par exemple).
une data source est un objet associé à une tableview. c'est elle qui l'allimente. Quand tu demandes à une tableview de faire reload par exemple, Ta tableview appelle la méthode tableview:objectValueForTableColumn:row: de sa data source autant de fois que sa data source a d'éléments. Ce nombre d"éléments est fourni par une autre méthode de sa data source qui est numberOfRowsInTableView:

exemple de data source

@interface UNEDataSource : NSObject <NSTableDataSource>
{
id *tableau[100][100];
int taille = 0;
}
- (id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)aTableColumn row:(int)rowIndex

- (void)tableView:(NSTableView *)aTableView setObjectValue:anObject forTableColumn:(NSTableColumn *)aTableColumn row:(int)rowIndex

- int)numberOfRowsInTableView:(NSTableView *)aTableView
@end

l'implémentation serait :

- int)numberOfRowsInTableView:(NSTableView *)aTableView
{
return taille;
}

- (id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)aTableColumn row:(int)rowIndex
{
int i,j;
if ([[aTableColumn identifier] stringValue] == "Nom") then j = 2
else j = 1;
return Tableau[rowIndex][j];
}

etc.....

Dans le controller de la tableview si vous avez appelé par myTableView son outlet, et par laDataSource sa datasource (déclarée par UNEDataSource *ladataSource)
l'association est faite par :

[myTbleView setDataSource:laDataSource];

Par contre si vous avez un bouton qui permet de calculer par exemple le total d'une colonne, vous pouver ajouter dans la data source la méthode SommeColumn: qui le fait. Par contre dans le controller vous faites :

[laDatasource SommeColumn:j];