(résolu) Bindings : je me relance...
LeChatNoir
Membre, Modérateur
Slt,
Bon je me relance dans les bindings. C'est pas que ca m'enchante mais bon, parait que ca fait gagner du temps (mais moi, ca me rend ).
Donc voilà le topo :
J'ai une hiérarchie d'objet perso sous forme d'arbre binaire (un objet a un père et n fils qui sont eux même des objet du meme type). Entre autre attribut, mes objets ont une description.
J'ai donc une outlineview qui représente visuellement cette hiérarchie (sans bindings).
Maintenant, j'aimerai que, quand on sélectionne un item dans l'outlineview, ca affiche le détail de l'objet sélectionné dans une autre vue. Quand je parles de détail, j'entend, les autres attributs de cet objet.
Et ça, j'aimerai que ca soit par bindings histoire de mettre un peu le nez dedans.
Donc comment faut il procéder ?
Je fais un objet tampon dans lequel je met les données de l'objet sélectionné dans mon outlineview et je "binde" cet objet là avec ma vue ?
J'ai du mal à voir par où commencer...
Bon je me relance dans les bindings. C'est pas que ca m'enchante mais bon, parait que ca fait gagner du temps (mais moi, ca me rend ).
Donc voilà le topo :
J'ai une hiérarchie d'objet perso sous forme d'arbre binaire (un objet a un père et n fils qui sont eux même des objet du meme type). Entre autre attribut, mes objets ont une description.
J'ai donc une outlineview qui représente visuellement cette hiérarchie (sans bindings).
Maintenant, j'aimerai que, quand on sélectionne un item dans l'outlineview, ca affiche le détail de l'objet sélectionné dans une autre vue. Quand je parles de détail, j'entend, les autres attributs de cet objet.
Et ça, j'aimerai que ca soit par bindings histoire de mettre un peu le nez dedans.
Donc comment faut il procéder ?
Je fais un objet tampon dans lequel je met les données de l'objet sélectionné dans mon outlineview et je "binde" cet objet là avec ma vue ?
J'ai du mal à voir par où commencer...
Connectez-vous ou Inscrivez-vous pour répondre.
Réponses
Mais comme tu ne veux pas faire du Tiger only, le plus simple est de binder tous tes champs à un NSObjectController. Puis tu utilises une méthode de délégué de NSOutlineView pour détecter le changement de ligne (outlineviewdidChangeSelection: de mémoire) dans laquelle tu modifies le content du nsobjectcontroller (tu peux récupérer le bon item avec itemAtRow:).
Je ne sais pas comment tu as deviné mais effectivement, je ne veux pas faire du Tiger Only. Je veux faire du "Panther at least :P".
Donc cet NSObjectController, je l'instancie direct dans IB (là , je fais appelle à mes souvenirs de quand j'avais abordé les bindings).
Ensuite, je binde tous mes champs visuels avec les propriétés de ce controller.
Donc dans le modèle MVC, les bindings entre Vue et controller, ca va (facile, ca se fait sous IB).
C'est la partie Controller/Modèle que je vois moins.
D'après ce que tu suggères, je n'utilise pas les bindings ?
Je vais simplement copier à la main ce qu'il faut dans mon objet controller ?
Et si j'ai une modification d'un champ (parce que ce sont des champs éditables), comment se passe la mise à jour de l'objet impacté dans mon modèle (mon arbre) ?
Merci !
J'avais oublié cet aspect. Dans le awakeFromNib du controller (celui que tu as fais, pas l'object controller), tu rajoutes des observer sur l'objectcontroller comme suit (par exemple pour la clé name):
avec écrit avant le @implementation
et tu rajoutes l'implémentation de la méthode qui sera exécutée pour lorsqu'il y aura modification d'une valeur observée:
L'utilisation la variable statique passée en argument de context permet de faire des comparaisons de pointeurs dans l'implémentation de observerValue, ce qui est nettement plus efficace que de passer par des [keypath isEqualToString:@selection.name];
À répéter pour toutes les colonnes de ta outline.
Ok. C'est cette partie sur laquelle je m'interroge : comment binder mon objectcontroller avec mon modèle ?
Sachant que mon modèle n'est pas instancié dans IB et qu'il s'agit d'un arbre.
L'outline ne sert effectivement que de déclencheur.
Mais quand je me relis, je me dis que je suis pas clair.
Clarifions donc la chose :
dans les préférences de Mail, tu as une liste avec les comptes paramétrés.
Quand tu sélectionne un compte, tu as le détail qui s'affiche à côté.
C'est exactement ça que je veux avec une notion de hierarchie entre les comptes en plus (bon ca, c'est peut être pas important).
J'ai donc mon arbre d'objets. Les noms et la hiérarchie sont affichées dans l'outlineview sans bindings.
A la sélection d'un item, je veux avoir le détail de l'objet correspondant.
Et pouvoir modifier ce détail.
Mais je ne vois toujours pas comment faire ca par bindings...
Comment binder mon arbre à mon objet controller...
Tu ne peux pas le faire par bindings, vu que pour gérer les arbres, il faut utiliser NSTreeController et ça ce n'est pas possible sous Panther. Donc tout ce que tu peux faire c'est utiliser des méthodes de délégué de ta outline pour etre informé du changement de sélection et modifier le content du objectController par code pour qu'il corresponde à la sélection (cf. première réponse).
Donc en résumé:
- le lien entre master et detail: code classique
- le "detail": bindings
- la mise à jour du master en fonction du détail: KVO
Dis moi si je suis bon à jeter ou pas :
- le lien master et détail : au changement de sélection dans mon outline, je copie le détail dans mon objet controller
- le détail : mon objet controller est bindé avec l'interface graphique => quand je change un champs de l'interface, le contenu de lo'objet controller change automatiquement,
- la mise à jour du master : dans mon controller principal, j'observe les changements des attributs de mon objet controller et les répercute sur mon vrai objet.
Alors, à la poubelle le ChatNoir ou pas encore ?
Merci Renaud !
pour la mise à jour du master: le objectController fait les modifications dans l'objet contenu dans ton arbre. Simplement ce qui est affiché dans la outline n'est pas à jour et donc il faut la "forcer" à se mettre à jour (le reloadItem: est comparable à un reloadData, mais c'est nettement plus sélectif comme mise à jour).
PS: un chat noir çe ne se jette pas à la poubelle, ça se cloue sur la porte d'entrée.
ou j'arrache un clou d'une de mes pattes (au choix).
Alors je n'ai qu'à observer l'attribut qui m'intéresse pour maj de l'outline.
C'est ce que tu disais dans ton 2eme post que je comprend mieux maintenant.
Mais je n'arrive pas à comprendre comment diable cet objectController va faire le lien avec mon objet à moi ?
C'est là qu'il faut le "binder". Par code donc ?
[objectController setContent:[outlineView itemAtRow:[outlineView selectedRow]]];
}[/tt]
Le faire par binding est possible aussi, mais pas directement avec la table:
1. Tu bindes le contentObject de objectController à ton controller. Comme keyPath, tu mets par exemple selection.
2. tu crées un variable d'instance selection (ou _selection suivant tes conventions). Et dans la méthode mentionnée ci-dessus, tu modifies ta variable d'instance.
Mais bon cela rajoute des étapes, et je ne sais pas si dans ton cas c'est vraiment utile.
Dans ce sens, je comprend.
Mais pour moi, on est dans le cas 1 - le lien entre master et détail.
Mais dans l'autre sens ?
Ou alors....
Le setContent ne fait peut être pas une copie ?
Et l'objectController pointe bien vers monObjetAMoi ?
Donc mon objet est impacté à chaque changement de l'objectController ?
C'est ça ? ou je me jette par la fenêtre ?
Allez, il y a une place près du feu et une coupelle de lait.
Il m'a fallut du temps mais c'est ce pu&@#n de setContent qui m'a mis dedans...
Merci, merci et encore merci !
Je tente ça ASAP (oh temps... suspend ton vol !) et je te paye ma tournée
...
de lait ::)
si ça marche
Serais tu où je peux avoir plus d'information sur cette classe : NSTreeController (en français si possible).
Bon j'ai fait mon objectController dans IB, je l'ai bindé à un TextField de mon interface et dans mon controleur, j'essaye d'afficher le contenu.
En gros, j'ai mis une key "host" et dans mon controleur, je fais un NSLog(@controleur : %@", [[moncontroleur selection] valueForKey:@host]);
Et y a jamais rien
Je pensais que cette simple manip permettait de binder l'objet controleur à l'interface mais c'est pas très concluant, que je saisisse du texte ou non... (validé ou non)..
Y a un truc qui m'échappe j'ai l'impression...
J'avais pas bien saisi le coup du type de l'objet gére par le controleur...
C'est génial les bindings !
J'arrive meme à binder le "enable" de mes champs selon la sélection dans la outline !
Bon je pense etre loin de tout maitriser mais le peu que je viens de decouvrir, c'est trop génial !
Merci encore Renaud !
je connais pas bien les TreeController mais il me semble que ca permet de binder un arbre ou une structure hiérarchique à une outlineview (voire une tableview ?).
Mais je vois pas trop le lien avec le D&Drop ?
Ou alors, Tiger pousse vraiment le vice plus loin dans les bindings et je n'ai pas vraiment creuser (vu que je veux que mon appli tourne pour Panther).
Pour le Drag&Drop dans une tableview, regarde la doc Apple sur les tablesview et plus particulièrement le topic "Drag&Drop with TableView".
C'est bien expliqué.
Et tu as le fameux exemple dans developper/examples/appkit et nommé DragNDrop OutlineView.
a+