Inhaltsverzeichnis
Tutorial: Sidebar an Dokument-Tabs binden
Dieses Tutorial zeigt, wie ein Add-in seine Sidebar-Views deklarativ an Dokumenttypen bindet. Der Host blendet die richtigen Panels automatisch ein, wenn der Benutzer zwischen Tabs wechselt. Ziel ist es, manuellen ShowPanel/HidePanel-Code vollständig durch Manifest-Konfiguration zu ersetzen.
Im Unterschied zu manueller Sidebar-Steuerung in DoActivated/DoDeactivated entfällt jeder Boilerplate-Code im Plugin. Der Vorteil besteht darin, dass der Host die Konsistenz garantiert: Beim Wechsel von einem WIS-Tab zu einem Settings-Tab oder zur Willkommensseite werden die WIS-Panels automatisch ausgeblendet und die passenden Settings-Panels eingeblendet.
Zurück zur Übersicht.
Ausgangslage
Ein Plugin namens „WIS“ hat drei Dokumenttypen und mehrere Sidebar-Panels:
| Dokumenttyp | Sidebar-Panel | Seite |
wis.proofPlan | Organisationsbaum, Filter | Primär |
wis.proofExec | Organisationsbaum, Filter | Primär |
wis.proofExec | Aufgaben-Detail | Sekundär |
wis.proofForecast | Filter | Primär |
Das Ziel: Wenn der Benutzer den Tab „Prüfausführung“ aktiviert, erscheinen Organisationsbaum und Filter links und das Aufgaben-Detail rechts. Wechselt er zur „Prüfvorschau“, bleibt nur der Filter links sichtbar.
Schritt 1: Manifest mit documentAffinity
Öffne die plugin.json des WIS-Plugins und ergänze die documentAffinity-Arrays in den View-Deklarationen:
{ "name": "wis", "displayName": "WIS Prüfungen", "version": "1.0.0", "publisher": "wvds", "kind": "native", "main": "bin/wis.plugin.dll", "activationEvents": [ "onCommand:wis.proofPlan.open", "onCommand:wis.proofExec.open", "onCommand:wis.proofForecast.open" ], "contributes": { "views": { "sidebar": [ { "id": "wis.orgTree", "title": "%nls.orgTree.title%", "icon": "codicon-list-tree", "containerId": "wis.navigation", "documentAffinity": ["wis.proofPlan", "wis.proofExec"] }, { "id": "wis.filter", "title": "%nls.filter.title%", "containerId": "wis.navigation", "documentAffinity": [ "wis.proofPlan", "wis.proofExec", "wis.proofForecast" ] } ], "secondary": [ { "id": "wis.taskDetail", "title": "%nls.taskDetail.title%", "documentAffinity": ["wis.proofExec"], "autoShow": true }, { "id": "wis.ruleDetail", "title": "%nls.ruleDetail.title%", "documentAffinity": ["wis.proofPlan"] } ] } } }
Einige Dinge fallen hier auf:
- Geteilte Affinität —
wis.filterist an alle drei Dokumenttypen gebunden: Prüfplan, Prüfausführung und Prüfvorschau. Egal welchen Tab der Benutzer aktiviert, der Filter ist immer sichtbar. - Eingeschränkte Affinität —
wis.orgTreeist nur an Plan und Exec gebunden. Bei der Vorschau verschwindet der Organisationsbaum. - Sekundäre Sidebar mit autoShow —
wis.taskDetailwird nur bei der Prüfausführung angezeigt, undautoShow: truesorgt dafür, dass die sekundäre Seitenleiste automatisch aufklappt. - Accordion-Gruppierung —
wis.orgTreeundwis.filterteilen sich diecontainerIdwis.navigation. Sie erscheinen als Accordion in der Seitenleiste.
Schritt 2: Plugin-Code vereinfachen
Entferne den manuellen Sidebar-Code aus den Dokument-Frames:
// VORHER — manueller Sidebar-Code (entfernen!): procedure TWISProofExecFrame.DoActivated; begin inherited; FHost.SideBar.ShowPanel('wis.orgTree'); FHost.SideBar.ShowPanel('wis.filter'); end; procedure TWISProofExecFrame.DoDeactivated; begin inherited; FHost.SideBar.HidePanel('wis.orgTree'); FHost.SideBar.HidePanel('wis.filter'); end; // NACHHER — kein Sidebar-Code mehr nötig: procedure TWISProofExecFrame.DoActivated; begin inherited; // Sidebar wird automatisch vom Host gesteuert. // Hier nur noch fachliche Logik (z.B. Daten laden). end;
Schritt 3: Verhalten verstehen
Der Host führt bei jedem Tab-Wechsel folgende Schritte aus:
- Dokumenttyp bestimmen — Der aktive Tab liefert seinen Dokumenttyp (z.B.
wis.proofExec). - Affinitäten auswerten — Der Host prüft alle registrierten Views: Ist der Dokumenttyp in der
documentAffinity-Liste enthalten? - Primäre Sidebar — Affine Views werden über die ActivityBar aktiviert. Der Benutzer sieht das korrekte Icon und das passende Accordion.
- Sekundäre Sidebar — Affine Views werden aktiviert. Bei
autoShow: truewird die sekundäre Seitenleiste automatisch sichtbar. - Optimierung — Wechselt der Benutzer zwischen zwei Tabs desselben Typs, passiert nichts (kein unnötiges Neuzeichnen).
Schritt 4: Testen
- Öffne den Tab „Prüfausführung“ → Organisationsbaum + Filter links, Aufgaben-Detail rechts.
- Öffne den Tab „Prüfvorschau“ → Nur Filter links, Aufgaben-Detail verschwindet.
- Öffne den Tab „Prüfplan“ → Organisationsbaum + Filter links, Regularium-Detail rechts.
- Öffne die Willkommensseite → Keine WIS-Panels sichtbar.
- Wechsle zurück zum „Prüfausführung“-Tab → Alles erscheint wieder.
Erweiterte Szenarien
Globale Views
Eine View ohne documentAffinity ist immer sichtbar:
{ "id": "wis.globalStatus", "title": "Status", "icon": "codicon-info" }
Diese View bleibt in der Seitenleiste, egal welcher Tab aktiv ist.
Mehrere Plugins, geteilte Sidebar
Plugin A und Plugin B können Views mit documentAffinity deklarieren, die auf ihre jeweiligen Dokumenttypen verweisen. Der Host verwaltet alle Affinities zentral. Beim Tab-Wechsel werden genau die Views des passenden Plugins angezeigt.
Benutzer-Override
Wenn der Benutzer ein Panel manuell schließt, merkt sich der Host diese Entscheidung. Das Panel wird nicht bei jedem Tab-Wechsel erneut aufgeklappt. Ein Layout-Reset (workbench.action.resetLayout) setzt alle Overrides zurück.
Zusammenfassung
| Aspekt | Ergebnis |
| Manifest-Feld | documentAffinity: string[] auf View-Ebene |
| Plugin-Code | Kein ShowPanel/HidePanel mehr nötig |
| Host-Verhalten | Automatisches Show/Hide bei Tab-Wechsel |
| Benutzer-Freiheit | Manuelle Overrides werden respektiert |
| Kompatibilität | Bestehende Views ohne documentAffinity bleiben unverändert |
Weiter zum Script-Command Tutorial oder zurück zur Übersicht.