NSBrowser, NSTreeController und NSTreeNode: Der Rateweg zum Ziel...

  • NSBrowser, NSTreeController und NSTreeNode: Der Rateweg zum Ziel...

    Hallo zusammen,

    gestern Abend hatte ich eine ganz einfache Aufgabenstellung. Ich wollte eine Baum-Hierarchie in einem NSBrowser anzeigen lassen. Die Hierarchie besteht aus zwei Ebenen. Die erste Ebene enthält Kategorien (Strings) und die zweite Ebene Unterkategorien (ebenfalls Strings):

    Kategorie 1
    Unterkategorie 1.1
    Unterkategorie 1.2
    Kategorie 2
    Unterkategorie 2.1
    ...

    Stundenlang habe ich gesucht, wie man einen NSBrowser an einen NSTreeController bindet. Gefunden habe ich fast ausschließlich Lösungen, die alle ein NSOutlineView an einen NSTreeController binden und dabei extrem viel Glue-Code erzeugen. Dokumentation von Apple gibt es dazu rein gar nichts. Jedenfalls habe ich nichts gefunden. Der Glue-Code kommt daher, da viele Programmierer ihre Bäume mit selbst programmierten TreeNodes realisieren und diese TreeNodes korrekt mit dem NSTreeController kommunizieren können müssen. Dabei gibt es, zumindestens in MacOS 10.5, eine NSTreeNode-Klasse, das Nutzdaten-Objekte (representedObject) unterstützt. Das muss allerdings erstmal herausfinden. Es ist daher ausreichend eine Nutzdaten-Klasse zu schreiben. In meinem Fall eine Kategorieklasse.

    Glücklicherweise bin ich heute morgen auf einen Blog gestossen, der auf sehr einfache Art und Weise zeigt, wie man einen NSTreeController an ein MSMutableArray mit NSTreeNodes bindet und anschließend die Hierarchie in einem NSOutlineView anzeigt: designedrecreations.blogspot.c…oller-and-nstreenode.html

    Doch wie geht das nun, wenn man zur Anzeige einen NSBrowser anstelle der NSOutlineView verwenden möchte? Nach langem ausprobieren habe ich herausgefunden, dass folgende Schritte durchzuführen sind:

    1. Der Content des NSBrowser muss an den NSTreeController gebunden werden. Der Controller Key ist dabei arrangeObjects und der Model Key Path bleibt leer.

    2. Content Values des NSBrowser muss ebenfalls an den NSTreeController gebunden werden. Der Controller Key ist auch arrangeObjects und der Model Key Path ist representedObject.name (Hinweis: representedObject enthält eine Instanz einer selbst geschriebenen Nutzerdaten-Klasse mit Property name).

    Nach diesen Schritten hat es endlich funktioniert. Lässt man einen der beiden Schritte weg funktioniert nichts. Gerade die Notwendigkeit von Schritt 1 ist für mich nicht einsichtig.

    Fazit:
    Ich finde die Binding-Geschichte von Cocoa insgesamt doch recht unintuitiv, undurchsichtig und dazu schlecht dokumentiert. Kennt jemand vielleicht ein gutes Buch oder auch eine gute Webseite, in der die Binding-Thematik mal genauer betrachtet wird? Insbesondere würde ich gerne wissen, wie die Bindings für die einzelnen UI-Elemente definiert werden müssen. Man kann ja schließlich nicht jedesmal raten.

    Viele Grüße
  • 1. Wie binden:
    dazu gibt' die "Cocoa Bindings Reference" in der Doku. Dort steht für jedes Oberflächenelement eine Auflistung und Beschreibung seiner Bindings.

    2: NSBrowser binden:
    Wenn ich mir im IB bei ausgewähltem NSBrowser die Binding-Palette ansehe, erscheint beim Mausdrüberbewegen über "Browser Content -> Content" der Tooltip "An NSTreecontroller instance that provides the content of the NSBrowser".

    Ich hab' noch nie einen NSBrowser benutzt, aber - nach etwas Erfahrung - findet man das in wenigen Minuten.

    Die Bindings sind nicht unbedingt undurchsichtig. Sie sind nur in vielen Oberflächenelementen implementiert und, nachdem es unterschiedliche Elemente gibt, unterschiedlich anzuwenden. Liegt in der Natur der Sache.

    Ich finde es aber super, daß Du Dir die Lösung selbst erarbeitet hast. Damit bist meiner Meinung nach auf dem besten Weg... :)

    No.
  • Hallo norbi,

    die "Cocoa Bindings Reference" habe ich auch gefunden. Aber mal ganz ehrlich: Die für den NSBrowser relevanten Bindings "content" und "contentValues" werden zusammen in dem Dokument in gerade mal drei Sätzen abgehandelt.

    Zum "contentValues"-Binding steht dort, dass "contentValues" ein String-Array sei, dessen Einträge im NSBrowser angezeigt werden. Diese Erklärung kann ich bei bestem Willen nicht mit meiner Lösung in Einklang bringen. Die alleinige Bindung von "content" genügt auch nicht, da zwar die Hierarchie angezeigt wird, aber alle Items den leeren String darstellen.

    Ich finde, dass die Dokumentation um einiges verbessert werden müsste. Kurze und aussagekräftige Beispiele wären auch nicht schlecht.

    Klar hast Du Recht: Erfahrung ist immer gut und hilft bei solchen Standard-Problemen ungemein. Da ich nun ca. 20 Jahre C++-Programmierung programmiere und bisher Oberflächen nur für Windows-Umgebungen entwickelt habe, erscheint mir Objective-C und das Cocoa-Konzept noch etwas fremd und ungewohnt. Naja, wenigstens gibt es ein Konzept. Ich fände es aber gut, wenn die Einstiegshürde etwas niedriger wäre. Hätte ich nicht vorher mal das Cocoa-Einstiegsbuch von Hillegass quer gelesen, hätte ich gleich aufhören können.

    Ich will auch nicht nur meckern. Wenn man einmal weiß wie Komponenten zu verwenden sind, macht die Entwicklung auch Spass. Viel Standard-Arbeit, wie zum Beispiel die Aktualisieung des Inhalts von UI-Komponenten, wird dem Programmierer vom Framework ja auch abgenommen.

    Viele Grüße