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ätwis.filter ist 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ätwis.orgTree ist nur an Plan und Exec gebunden. Bei der Vorschau verschwindet der Organisationsbaum.
  • Sekundäre Sidebar mit autoShowwis.taskDetail wird nur bei der Prüfausführung angezeigt, und autoShow: true sorgt dafür, dass die sekundäre Seitenleiste automatisch aufklappt.
  • Accordion-Gruppierungwis.orgTree und wis.filter teilen sich die containerId wis.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:

  1. Dokumenttyp bestimmen — Der aktive Tab liefert seinen Dokumenttyp (z.B. wis.proofExec).
  2. Affinitäten auswerten — Der Host prüft alle registrierten Views: Ist der Dokumenttyp in der documentAffinity-Liste enthalten?
  3. Primäre Sidebar — Affine Views werden über die ActivityBar aktiviert. Der Benutzer sieht das korrekte Icon und das passende Accordion.
  4. Sekundäre Sidebar — Affine Views werden aktiviert. Bei autoShow: true wird die sekundäre Seitenleiste automatisch sichtbar.
  5. Optimierung — Wechselt der Benutzer zwischen zwei Tabs desselben Typs, passiert nichts (kein unnötiges Neuzeichnen).

Schritt 4: Testen

  1. Öffne den Tab „Prüfausführung“ → Organisationsbaum + Filter links, Aufgaben-Detail rechts.
  2. Öffne den Tab „Prüfvorschau“ → Nur Filter links, Aufgaben-Detail verschwindet.
  3. Öffne den Tab „Prüfplan“ → Organisationsbaum + Filter links, Regularium-Detail rechts.
  4. Öffne die Willkommensseite → Keine WIS-Panels sichtbar.
  5. 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.

Zuletzt geändert: den 18.03.2026 um 23:21