Forcer le rafraà®chissement des contrôles bindés

CéroceCéroce Membre, Modérateur
10:59 modifié dans API AppKit #1
Bonjour à  tous, j'en appelle aujourd'hui aux spécialistes des bindings.

Voici ce que je cherche à  faire: j'ai une application graphique multi-documents dans laquelle je souhaite modifier les attributs des formes géométriques grâce à  un inspecteur. Considérons par exemple le curseur qui permet de changer l'épaisseur du trait. Sa valeur est bindée sur
[file's owner].currentDocument.figuresArrayController.selection.style.thickness

file's owner est le Window Controller qui gère l'inspecteur. Il possède une variable d'instance currentDocument qui pointe sur le document actuel. Les documents envoient des notifications pour signaler qu'il passent au premier plan, et currentDocument est bien mis à  jour.

Par ailleurs, déplacer le curseur modifie effectivement l'épaisseur du trait (-> le slider influe sur le modèle). Le problème, c'est que lors d'un changement de document, le curseur ne reflète pas le modèle (-> le modèle n'influe pas sur le slider).

Mon intuition est qu'il faut rafraà®chir les bindings des contrôles de l'inspecteur pour qu'ils prennent en compte le changement de valeur de currentDocument lors du passage d'un document au premier plan.

Savez-vous comment rafraà®chir ces bindings ?

Réponses

  • Philippe49Philippe49 Membre
    août 2008 modifié #2
    Si tu changes le document, il y a de fortes chances que le binding n'ait plus lieu avec l'objet que tu veux.
    [file's owner].currentDocument.figuresArrayController.selection.style.thickness

    Dans cette organisation, ne peut-on essayer un unbind sur le binding avec l'ancien document, suivi d'un bind sur le nouveau , ce qui signifie que le binding serait à  réaliser dans le code du windowController.

  • CéroceCéroce Membre, Modérateur
    10:59 modifié #3
    Merci Philippe de ta réponse !

    Malheureusement, c'est un peu ce que je craignais, je ne vais plus pouvoir binder sous IB, il va falloir le faire à  la main (la fainéantise est une bonne chose, ça force à  chercher des solutions astucieuses).

    Bon. J'essaie ça.
  • CéroceCéroce Membre, Modérateur
    10:59 modifié #4
    Comme je veux binder avec Interface Builder, mon idée était de parcourir tous les contrôles contenus dans une vue, de prendre les infos sur chaque binding, de le débinder et de rebinder à  nouveau pour qu'il prenne en compte le nouveau document.
    Quelque chose comme ça:

    - (void) _udpateBindingsInView:(NSView*)view<br />{<br />	// List every subviews that compose it<br />	NSArray*	subviewsArray = [view subviews];<br />	NSEnumerator*	subviewEnum = [subviewsArray objectEnumerator];<br />	NSView*			subview;<br />	<br />	while(subview = [subviewEnum nextObject])<br />	{<br />		// List every bindings of the subview<br />		NSArray* exposedBindings = [subview exposedBindings];<br />		NSEnumerator* bindingsEnum = [exposedBindings objectEnumerator];<br />		NSString*	binding;<br />		<br />		while(binding = [bindingsEnum nextObject])<br />		{<br />			// Unbind, then rebind with the same binding<br />			NSDictionary* bindingInfo = [subview infoForBinding:binding];			<br />			[subview unbind:binding];<br />			[subview bind:binding toObject:[bindingInfo objectForKey:NSObservedObjectKey] withKeyPath:[bindingInfo objectForKey:NSObservedKeyPathKey] options:[bindingInfo objectForKey:NSOptionsKey]];<br />			<br />		}<br />	}<br />}
    


    Malheureusement, la méthode exposedBindings ne renvoie que deux bindings: hidden et tooltip. Je n'ai pas trouvé d'autre méthode pour obtenir la liste des bindings.

    Pour en revenir à  mon problème, j'ai trouvé sur ce message intéressant: http://lists.apple.com/archives/Cocoa-dev//2004/Sep/msg01054.html.

    Il dit surtout que pour binder un inspecteur, le plus simple est de binder sur [Shared Application].mainWindow.windowController.document.
    J'ai donc essayé de binder mon slider sur [application].mainWindow.windowController.document.figuresArrayController.selection.style.thickness et ça marche !

    Bref, ça résout mon problème, mais ça ne répond pas à  ma question.
Connectez-vous ou Inscrivez-vous pour répondre.