Récupérer les données à  partir d'une sélection d'un NSTableView

mattma59mattma59 Membre
juillet 2004 modifié dans API AppKit #1
Salut tout le monde !!!

j'ai une question sur les NSTableView. J'ai fait les tutoriels sur le site de ProjectOmega et notamment le carnet d'adresse ou on utilise pour la 1e fois les tableaux.
On peut insérer une personne en selectionnant une ligne dans le tableau. Moi ce que je voudrais rajouter, c'est l'inverse, c'est que quand je selectionne une ligne du tableau, les champs se remplissent automatiquement avec les valeurs du tableau.

J'espere avoir ete assez clair.

Merci pour votre aide

Matthieu

Réponses

  • TMXTMX Membre
    23:29 modifié #2
    Salut Matthieu,

    Tu peux récupérer les valeurs d'une NSTableView en implémentant dans ton programme la méthode :
    - (id)tableView:(NSTableView *)table objectValueForTableColumn:(NSTableColumn *)column row:(int)rowIndex

    Dans cette méthode, tu récupérès un id qui est la valeur d'une colonne donnée pour une ligne donnée.

    Dans ton IBAction liée à ta NSTableView, tu récupères l'index de la ligne sélectionnée en utilisant la méthode "selectedRow" de la classe NSTableView et la colonne en utilisant la métode "selectedColumn".

    Tu auras plus d'infos en allant à l'adresse suivante :

    http://developer.apple.com/documentation/Cocoa/Conceptual/TableView/Tasks/UsingTableDataSource.html

    J'espère t'avoir un peu aidé.

    A+
    TMX
  • mattma59mattma59 Membre
    23:29 modifié #3
    Merci pour ta réponse, je regarderai ca ce week end.
    Je viens de voir que le tuto de ClicCool sur macfr parlait des bindings et des tableaux, y a peut etre moyen de mettre a jour mes champs a partir de cela.
  • ClicCoolClicCool Membre
    23:29 modifié #4
    Oui !!
    C'est exactement ça, la phylosophie des bindings sur les TablesViews est inverse du tuto de ProjectOmega,
    Et en effet les bindings mettrons à jours des NSTextFields liés en fonction de la ligne sélectionnée.

    Et au passage bienvenu sur objective-Cocoa.org :)
    Et si t'as des questions, je suis aussi à ta disposition ici même ;)
  • juillet 2004 modifié #5
    dans 1089273014:

    peux récupérer les valeurs d'une NSTableView en implémentant dans ton programme la méthode :
    - (id)tableView:(NSTableView *)table objectValueForTableColumn:(NSTableColumn *)column row:(int)rowIndex

    Dans cette méthode, tu récupérès un id qui est la valeur d'une colonne donnée pour une ligne donnée.

    Dans ton IBAction liée à ta NSTableView, tu récupères l'index de la ligne sélectionnée en utilisant la méthode "selectedRow" de la classe NSTableView et la colonne en utilisant la métode "selectedColumn".


    Euh, je crains qu'il n'y ait un problème avec ton code. Avec ça, il ne peut avoir que les données correspondant à la colonne et à la ligne sélectionnée, et il veut toutes les données liées à une ligne. Pour partir dans ce que tu proposes, il faut alors faire un boucle, et ça risque de ne pas être évident.

    La solution est en fait beaucoup plus simple. Les données sont stockées dans des dictionnaires, qui sont eux même stockés dans un tableau.

    Donc il suffit de faire (les noms ne correspondent pas):
    <br />- (void)tableViewSelectionDidChange:(NSNotification *)aNotification { //Cette m&eacute;thode est appel&eacute;e quand l&#39;utilisateur change de ligne<br /><br />NSDictionary selectedItem = [records objectAtIndex:[tableView selectedRow]];<br /><br />[firstNameField setStringValue:[selectedItem objectForKey:@&quot;First Name&quot;]];<br />[lastNameField setStringValue:[selectedItem objectForKey:@&quot;Last Name&quot;]];<br />...<br /><br />}<br />
    


    Et pour que ça marche, il faut que le controlleur soit le delegate de la table (procède de la même façon que pour le datasource, un même objet peut être à la fois delegate et datasource).
  • mattma59mattma59 Membre
    juillet 2004 modifié #6
    Merci pour vos réponses et votre accueil !!!

    Depuis, j'ai regardé le magnifique travail de cliccool sur macfr et j'ai utilisé les bindings pour mon appli. C'est le résultat que je voulais. ;)
    Merci Arldon pour ta solution, je regarderai comment fonctionnent les delegates



    je viens d'essayer avec les delegates, ca marche aussi
  • ClicCoolClicCool Membre
    23:29 modifié #7
    Merci, y'a pas à  dire, ça fait toujours plaisir  :)
  • mattma59mattma59 Membre
    23:29 modifié #8
    Je profite que vous etes la pour poser une autre question.
    Dans mon appli, j'ai un NSTableView, plusieurs NSTextFields et 2 NSButton (Ajout et Suppression)
    Sur ces 2 boutons, j'ai mis les connexions correspondantes (add et remove). Mais si on appuie plusieurs fois sur Ajout, il me crée autant de lignes (ce qui est normal jusque là ). Ce que je voudrais, c'est bloquer le bouton ajout une fois que l'on a clique dessus pour eviter justement d'avoir plusieurs lignes vierges.
    Peut on le faire avec les bindings? (j'ai rien trouve la dessus mais les bindings me surprennent tellement on sait jamais)

    Merci
    matt
  • ClicCoolClicCool Membre
    juillet 2004 modifié #9
    Ben là , j'ai pas trouvé directement par les bindings, faut coder un peu

    - soit tu sous classe ton NSArrayController pour "intercepter" les add et insert et tu y case un message d'inactivation à  ton bouton ... puis de réactivation en temps opportuns.

    - soit, plus simplement, te branche le bouton sur une IBAction qui envoizeun message d'inactivation à  ton bouton ... puis de réactivation en temps opportuns.

    le pb c'est QUAND (et où) tu le réactives ?
  • ClicCoolClicCool Membre
    juillet 2004 modifié #10
    salut mattma59,

    j'ai écrit plus vite que ton ombre ;) :P
    y'a une 3ème solution avec les bindings:

    En sous classant le NSArrayController tu peux dériver  sa - (BOOL)canAdd (de NSController) ou - (BOOL)canInsert (de NSArrayController) pour renvoyer non quand une ligne n'est pas "finie" et binder la propriété "Enable " de ton bouton sur "canAdd"  (et/ou "canInsert") de ton NSArrayController.
    Reste à  savoir quand ton "canAdd" renvérra faux ou vrai mais là  c'est toi qui choisi ;)

    ça parrait plus propre mais j'ai jammais essayé.
    Si tu le fais tiens nous au courrant :)
  • odjauodjau Membre
    23:29 modifié #11
    dans 1090148591:

    ?si on appuie plusieurs fois sur Ajout, il me crée autant de lignes (ce qui est normal jusque là ). Ce que je voudrais, c'est bloquer le bouton ajout une fois que l'on a clique dessus pour eviter justement d'avoir plusieurs lignes vierges.


    Personnelement je trouve qu'essayer de bloquer le bouton "ajout" c'est pas très érgonomique et que ça peut entrainer des "dysfonctionnement" (la touche bloqué) qu'un utlilisateur peut ne pas comprendre...
    Par contre si le bouton "ajout" crée un élément vide (ligne vierge), c'est pas génial non plus, je pense que plus simplement il suffit que le add crée une valeur par défaut. Faut peut-être rejouter un petit quelque chose dans la méthode -(id)init de l'objet qui est empilé dans NSTableView ?

    Je contourne un peu le problème mais bon, j'ai peu l'impression qu'on part sur une solution un peu moins "usine à  gaz?
    Qu'en pensez vous ?
  • ClicCoolClicCool Membre
    juillet 2004 modifié #12
    dans 1090176358:

    Personnelement je trouve qu'essayer de bloquer le bouton "ajout" c'est pas très érgonomique...
    ... il suffit que le add crée une valeur par défaut. Faut peut-être rejouter un petit quelque chose dans la méthode -(id)init de l'objet qui est empilé dans NSTableView ?

    Je penses comme toi, pour l"ergonomie

    Pour l'initialisation de l'objet ajouté sur des valeurs par défaults, pas forcément:

    - Si c'est juste pour placer un nom par défault identique à  tous les nouveaux éléments, un placeholder permet d'afficher quelque chose comme "nouvel Element sans nom" par exemple. Et celà  sans créer d'objet standard associé à  la clef et donc sans consommer de mémoire (y compris sur le disque lors de la sauvegarde)

    - Si par contre on doit avoir des valeurs par défault variables, comme un Numéro de Référence basé sur un compteur ou une date-heure, ou si certaines valeurs ne peuvent être nulles, là  l'initialisation de l'objet est nécessaire.

    - Enfin si certaine valeurs doivent être uniques, là  l'initialisation risque de ne plus être suffisante

    mais alors, pour l'ergonomie, j'opterai plutôt pour l'ouverture d'une feuille ou une fenêtre de saisie d'un nouvel élément.
  • odjauodjau Membre
    23:29 modifié #13
    dans 1090187914:

    - Si c'est juste pour placer un nom par défault identique à  tous les nouveaux éléments, un placeholder permet d'afficher quelque chose comme "nouvel Element sans nom" par exemple. Et celà  sans créer d'objet standard associé à  la clef et donc sans consommer de mémoire (y compris sur le disque lors de la sauvegarde)


    heu... le placeholder... ça consiste en quoi ?  :-\ j'ai pas trouvé dans la doc des developperTools...
  • muqaddarmuqaddar Administrateur
    23:29 modifié #14
    J'allais le demander... :-)
  • ClicCoolClicCool Membre
    23:29 modifié #15
    Un placeholder c'est celui "qui garde la place" dans certaines circonctances.

    Avec les Bindings on peut utiliser:

    • @NSNullPlaceholderL'objet-valeur utilisé comme NSNullPlaceholder sera utilisé si la clef bindée renvoie nil.
    • @NSNoSelectionPlaceholder Est utilisé si un binding sur un tableau n'a pas de sélection courrante.
      Par exemple un NSTextField bindé sur  "controller key": "selection" ModelKeyPath: "notreClefAAfficher"
      Affichera @no selection ou le NoSelectionPlaceholder qu'on aura choisi s'il n'y a pas de sélection.
    • @NSMultipleValuesPlaceholder Est utilisé de la même façon en cas de sélection multiple


    Dans le cas qui nous préoccupe il suffit de placer la NSString @nouvel élément sans nom comme NullPlaceholder pour que le nouvel élément, qui n'a pas encore de valeur affectée à  ses clefs, affiche un texte indentifiable par défaut.

    Si vous ne parvenez pas à  le faire dites le :)
  • odjauodjau Membre
    23:29 modifié #16
    No problem, ça marche  :)

    Merci qui, merci CilcCool  ;D

    @+
  • 23:29 modifié #17
    le placeHolder c'est aussi comme dans safari, sur le champ de rechercge, tu vois écrit Google en grisé, c'est le placeHolder du NSSearchField, qui permet de te donner des informations sans modifier le contenu du textField
  • TiffTiff Membre
    23:29 modifié #18
    Oui, j'aime beaucoup les placeHolder, très utiles, et pas compliqué du tout.
  • muqaddarmuqaddar Administrateur
    23:29 modifié #19
    Bein chez moi, cela ne marche pas. J'ai mis "Pas de selection" comme place holder, et il garde son "No Selection" par défaut... snif.
  • muqaddarmuqaddar Administrateur
    23:29 modifié #20
    Ah ça y est ça marche ! Pardon. Glops.
Connectez-vous ou Inscrivez-vous pour répondre.