System.Windows.Forms

Namespace: System.Windows.Forms

Mit System.Windows.Forms können Forms erstellt werden, die wie ein Windows-Fenster agieren. Um es nutzen zu können, muss das entsprechende Assembly eingebunden werden:

Add-Type -AssemblyName System.Windows.Forms

CheckBox

Namespace: System.Windows.Forms

Eigenschaften / Propertys

Die CheckBox gehört zu diesen Controls, die harmlos aussehen… bis man plötzlich merkt, dass daran halbe UI-Logik hängt.

Denn technisch gesehen ist sie nicht einfach nur „an oder aus“.
Sie ist oft ein kleiner Schalter für:

Und plötzlich hängt daran alles. Willkommen im Club menschlicher Selbstüberschätzung.


# CheckBox erstellen
$checkBox = New-Object System.Windows.Forms.CheckBox
$checkBoxNew = [System.Windows.Forms.CheckBox]::new()

# Text
$checkBox.Text = "Dark Mode aktivieren"

# Position & Größe
$checkBox.Location = New-Object System.Drawing.Point(10,10)
$checkBox.AutoSize = $true

# Standardmäßig aktiv
$checkBox.Checked = $true

📥 Werte auslesen

# Aktiviert?
$state = $checkBox.Checked

# Exakter Zustand
$checkState = $checkBox.CheckState





Events - CheckBox

✅ CheckedChanged

Das wichtigste Event der ganzen CheckBox.

Wird ausgelöst, sobald sich der Zustand ändert.

$checkBox.Add_CheckedChanged({
    Write-Host "CheckBox Zustand:" $checkBox.Checked
})

👉 Das ist normalerweise das Event, das du wirklich willst.

Nicht Click.

Nicht MouseDown.

Nicht irgendwelche kreativen Konstruktionen aus emotionalem Kontrollverlust.


🔁 CheckStateChanged

Ähnlich wie CheckedChanged, aber für CheckState.

Relevant bei ThreeState.

$checkBox.ThreeState = $true

$checkBox.Add_CheckStateChanged({
    Write-Host "State:" $checkBox.CheckState
})

👉 Ohne ThreeState bringt dir das meistens exakt gar nichts.


🖱️ Click

Feuert bei jedem Klick auf die CheckBox.

$checkBox.Add_Click({
    Write-Host "CheckBox wurde geklickt"
})

Das Problem:

Click bedeutet nicht automatisch, dass sich der Zustand geändert hat.

Das vergessen Leute ständig und bauen dadurch doppelte Logik.


⌨️ KeyDown

Für Tastatursteuerung.

$checkBox.Add_KeyDown({
    Write-Host $_.KeyCode
})

👉 Viele vergessen komplett, dass Benutzer auch Tastaturen besitzen. Faszinierende gesellschaftliche Entwicklung eigentlich.



🧩 ThreeState

Normalerweise kennt eine CheckBox nur:

Checked
Unchecked

Mit ThreeState kommt hinzu:

Indeterminate

Beispiel:

$checkBox.ThreeState = $true
$checkBox.CheckState = "Indeterminate"

Das nutzt man oft für:

Klassisches Beispiel:

Ordner-Auswahl mit Unterelementen
Einige aktiviert → graues Kästchen


🎨 Appearance = Button

Das hier kennen überraschend viele nicht:

$checkBox.Appearance = "Button"

Dann wird aus der CheckBox ein Toggle-Button.

$checkBox.Text = "Musik aktivieren"
$checkBox.Appearance = "Button"

👉 Sehr praktisch für moderne UI-Schalter.

Und ja, technisch bleibt es trotzdem einfach nur eine CheckBox im Kostüm. Menschen machen das übrigens auch ständig.


⚠️ Typische Stolperfallen

$checkBox.Checked = $true

→ Event wird trotzdem ausgelöst



if ($checkBox.Checked)

→ ignoriert Indeterminate


Dann ändert die CheckBox ihren Zustand nicht selbst.

$checkBox.AutoCheck = $false

👉 Ab da bist du verantwortlich.

Glückwunsch. Du bist offiziell der Zustand-Manager deines kleinen Universums.


🧩 Best Practice


Ich greif einen Punkt raus, den viele komplett unterschätzen:

Eine CheckBox ist kein Datenspeicher. Sie ist nur UI.

Das hier:

if ($checkBox.Checked)

…ist kein „Systemzustand“.

Das ist nur die aktuelle Anzeige im Interface.

Wenn deine komplette Logik davon abhängt, ob irgendein Kästchen gerade angehakt ist, endet dein Projekt irgendwann wie ein Keller voller Verlängerungskabel. Funktioniert irgendwie. Bis jemand dagegen tritt.

CheckedListBox

Namespace: System.Windows.Forms

Properties / Eigenschaften

Verhalten (Behavior)


Daten / Inhalt (Data)


Layout & Position


Aussehen (Appearance)


Meta / System


Größe

Die CheckedListBox ist im Grunde eine ListBox mit eingebauten Checkboxen. 

CheckedListBox erstellen

$clb = New-Object System.Windows.Forms.CheckedListBox
$clbNew = [System.Windows.Forms.CheckedListBox]::new()

Items hinzufügen

$clb.Items.Add("Apfel")
$clb.Items.Add("Banane")
$clb.Items.AddRange(@("Orange","Mango","Traube"))

📥 Werte auslesen

# Alle angehakten Items
$checked = $clb.CheckedItems

# Indizes
$indices = $clb.CheckedIndices

# Einzelnes Item (nur Fokus, nicht Check!)
$selected = $clb.SelectedItem

👉 Wichtiger Unterschied:
SelectedItemCheckedItems


Events - CheckedListBox

Events
Interaktion
Maus
Tastatur
Fokus
Darstellung / Layout
Zustand
Aussehen
Datenbindung
$sender 

→ Das Objekt, das das Event ausgelöst hat. Meistens die CheckedListBox selbst

$e

→ Zusatzinfos zum Event → was genau ist passiert

$CheckedListBox.Add_Click({
  param($sender, $e)

  $sender.BackColor = "Red"
})

ItemCheck

$CheckedListBox.Add_ItemCheck({
  param($sender, $e)

  $e.Index
  $e.NewValue
  $e.CurrentValue
})

Tipps & Tricks - CheckedListBox

Check direkt beim Klick

$checkListBox.CheckOnClick = $true

Alle gesetzten Werte holen

$clb.CheckedItems | ForEach-Object {
$_
}

🧩 Check programmatisch setzen

$clb.SetItemChecked(0, $true)

⚠️ Typische Stolperfallen

🧩 Mentales Modell

Die CheckedListBox hat zwei Zustände gleichzeitig:

  1. Fokus (SelectedItem)
  2. Check-Zustand (CheckedItems)

Wenn du das vermischst → Chaos.

🧩 Best Practice

DialogResult

Überblick

System.Windows.Forms.DialogResult ist ein Enum, das den Rückgabewert eines Dialogfensters beschreibt. Es gibt an, wie ein Dialog geschlossen wurde, zum Beispiel durch Klick auf OK, Cancel, Yes oder No.

Der Typ wird hauptsächlich in Verbindung mit Windows-Forms-Dialogen wie MessageBox oder OpenFileDialog verwendet.

Typ

Enum (feste, benannte Werte; intern numerisch)

Werte (Auszug)

Wert Bedeutung
None Kein Ergebnis oder Dialog noch nicht geschlossen
OK OK-Schaltfläche gedrückt
Cancel Abbrechen gedrückt oder Fenster geschlossen
Yes Ja gedrückt
No Nein gedrückt
Abort Abbruch
Retry Wiederholen
Ignore Ignorieren

Nicht jeder Dialog liefert jeden Wert zurück.
Die verfügbaren Rückgabewerte hängen von den verwendeten Buttons ab.

Verwendung:

x (x)

x (x)

FolderBrowserDialog

Öffnet einen Dialog zur Auswahl eines Ordners.
Typischer Windows-"Ordner auswählen"-Dialog. Weil Menschen offenbar selbst beim Auswählen eines Verzeichnisses noch eine GUI brauchen und nicht einfach "C:\Irgendwas" eintippen können.


Konstruktor

$dialog = [System.Windows.Forms.FolderBrowserDialog]::new()

Eigenschaften

Description

Text oberhalb des Verzeichnisbaums.

$dialog.Description = "Wähle einen Zielordner aus"

SelectedPath

Der aktuell ausgewählte Ordnerpfad.

Kann:

$dialog.SelectedPath = "C:\Temp"
$dialog.SelectedPath

RootFolder

Legt fest, ab welchem Systemordner der Benutzer navigieren darf.

Verwendet Werte aus:

[System.Environment+SpecialFolder]

Beispiele:

$dialog.RootFolder = [System.Environment+SpecialFolder]::Desktop

ShowNewFolderButton

Bestimmt, ob die Schaltfläche "Neuen Ordner erstellen" angezeigt wird.

$dialog.ShowNewFolderButton = $true

Methoden

ShowDialog()

Öffnet den Dialog.

Rückgabewert:

[System.Windows.Forms.DialogResult]

Meist:

$result = $dialog.ShowDialog()

Dispose()

Gibt verwendete Ressourcen frei.

Technisch nicht immer zwingend nötig, aber sauberer. Besonders wenn man viele Dialoge erzeugt. Windows Forms sammelt sonst gerne kleinen Müll an wie ein Messie mit Kabelschublade.

$dialog.Dispose()

Einfaches Beispiel

Add-Type -AssemblyName System.Windows.Forms

$dialog = [System.Windows.Forms.FolderBrowserDialog]::new()

$dialog.Description = "Wähle einen Ordner"
$dialog.SelectedPath = "$env:USERPROFILE\Desktop"
$dialog.ShowNewFolderButton = $true

if ($dialog.ShowDialog() -eq "OK") {
    $dialog.SelectedPath
}

$dialog.Dispose()

Typischer Ablauf

Dialog erstellen
    ↓
Eigenschaften setzen
    ↓
ShowDialog()
    ↓
DialogResult prüfen
    ↓
SelectedPath verwenden
    ↓
Dispose()

Wichtige Hinweise

SelectedPath setzt auch den Startordner

Viele denken:

"RootFolder bestimmt den Startordner"

Nein.
RootFolder begrenzt nur den sichtbaren Bereich.

Der tatsächliche Startordner kommt meistens von:

SelectedPath

Benutzer kann abbrechen

Darum niemals direkt:

$dialog.SelectedPath

verwenden ohne vorher:

ShowDialog()

zu prüfen.

Sonst arbeitest du eventuell mit leerem Inhalt weiter. Und plötzlich löscht ein Skript rekursiv "\". Kleine Eskalation. Riesige Wirkung.


Unterschied zu OpenFileDialog

Dialog Zweck
FolderBrowserDialog Ordner auswählen
OpenFileDialog Datei auswählen
SaveFileDialog Speicherort + Dateiname auswählen

Typische Verwendung


Minimalbeispiel

if ($dialog.ShowDialog() -eq "OK") {
    $path = $dialog.SelectedPath
}

Das ist im Grunde der Kern von allem hier. Der Rest ist Komfort, Einschränkung oder kosmetische Kontrolle über das Windows-Chaos von 2003.

Form

Namespace: System.Windows.Forms

Properties / Eigenschaften

Eigenschaften, die sich gegenseitig beeinflussen

Eine Form ist das Hauptfenster deiner Anwendung.
Sie ist der Container für alle anderen Controls.


Grundidee

Die Form ist die Bühne.


Typischer Ablauf

  1. Properties setzen
  2. Controls hinzufügen
  3. Events definieren
  4. Form anzeigen (Show() / ShowDialog())

Form erstellen

# Klassisch
$form = New-Object System.Windows.Forms.Form

# .NET-Style
$form = [System.Windows.Forms.Form]::new()

Form anzeigen

# Nicht blockierend
$form.Show()

# Modal (blockierend)
$form.ShowDialog()

Controls hinzufügen

$form.Controls.Add($button)
$form.Controls.AddRange(@($label, $textbox))

Layout & Verhalten

$form.Size = [System.Drawing.Size]::new(400, 300)
$form.StartPosition = "CenterScreen"
$form.TopMost = $true
$form.FormBorderStyle = "FixedDialog"

 


Events - Form

$form.Add_*
  param($sender, $e)

Load

Wird beim Initialisieren der Form ausgelöst

$form.Add_Load({
    Write-Host "Form lädt"
})

Shown

Wird nach dem Anzeigen ausgelöst

$form.Add_Shown({
    Write-Host "Form sichtbar"
})

FormClosing

Vor dem Schließen (kann verhindert werden)

$form.Add_FormClosing({
    param($sender, $e)

    $e.Cancel = $true  # verhindert Schließen
})

FormClosed

Nach dem Schließen

$form.Add_FormClosed({
    Write-Host "Form geschlossen"
})

Resize

Bei Größenänderung

$form.Add_Resize({
    Write-Host "Neue Größe: $($this.Size)"
})

Tipps & Tricks - Form


Typische Stolperfallen


Mentales Modell

Die Form ist der Lebenszyklus-Controller deiner UI.

Sie bestimmt:


Wann sinnvoll?


Wann problematisch?

Label

Ein Label ist ein reines Anzeige-Control für Text.
Es dient zur Beschreibung, Anzeige oder Strukturierung von UI-Inhalten.

Ein Label ist nicht für direkte Benutzerinteraktion vorgesehen, kann jedoch auf Ereignisse wie Mausklicks reagieren.

Label erstellen

# Klassisch
$label = New-Object System.Windows.Forms.Label

# .NET-Style
$label = [System.Windows.Forms.Label]::new()

Eigenschaften - Label

Eigenschaften
geerbt von Control

Text

Typ: system.String

Die Eigenschaft Text legt den angezeigten Inhalt eines Labels fest.

$label.Text = "Hallo Welt"

# Mehrzeilig
$label.Text = "Zeile 1`nZeile 2"

PowerShell macht implizite Konvertierung:

$Label.Text = 123

funktioniert, weil es intern zu "123" wird.


AutoSize

Typ: System.Boolean

Die Eigenschaft AutoSize bestimmt, ob sich das Label automatisch an die Größe seines Inhalts anpasst.

# Automatische Größe
$label.AutoSize = $true

Size

Typ: System.Drawing.Size

# Feste Größe
$label.Size = [System.Drawing.Size]::new(200, 30)

TextAlign

Typ: System.Drawing.ContentAlignment

# Text zentrieren
$label.TextAlign = "MiddleCenter"

Events - Label

Events
Interaktion (User Input)
Zustand / Inhalt
Layout
Darstellung (Rendering)
Aussehen
$label.Add_*
  param($sender, $e)

Interaktionen (User Input)

Click / DoubleClick / MouseDown
# Click
$label.Add_Click({
    param($sender, $e)

    Write-Host "Auf das Label wurde geklickt"
})

# DoubleClick
$label.Add_DoubleClick({
  param($sender, $e)

  Write-Host "Auf das Label wurde doppelt geklickt"
])

# MouseDown
$label.Add_MouseDown({
  param($sender, $e)

  Write-Host "Auf das Label wurde entweder mit links oder rechts geklickt"
})
MouseEnter / MouseLeave

Mit MouseEnter und MouseLeave sind Hover-Effekte möglich

$label.Add_MouseEnter({
    $this.ForeColor = "Red"
})

$label.Add_MouseLeave({
    $this.ForeColor = "Black"
})
MouseMove

Mausbewegung innerhalb vom Label

$label.Add_MouseMove({
    param($sender, $e)
})
TextChanged

Wird ausgelöst, wenn sich der Text ändert

$label.Add_TextChanged({
    param($sender, $e)

    Write-Host "Neuer Text: $($sender.Text)"
})


Tipps & Tricks - Label


Typische Stolperfallen


Mentales Modell

Ein Label ist UI-Deko mit Bedeutung.

Es erklärt dem Benutzer, was andere Controls tun oder zeigt Status an.


Wann sinnvoll?


Wann vermeiden?

ListBox

Namespace: System.Windows.Forms

Properties / Eigenschaften
  • Property – Standardwert
    Beschreibung oder Erläuterung der Eigenschaft

  • AllowDrop $false
    Erlaubt Drag & Drop auf die ListBox
  • Anchor (Top, Left)
    Bestimmt, wie sich die ListBox bei Größenänderung des Containers verhält
  • BackColorSystemColors.Window
    Hintergrundfarbe der ListBox
  • BorderStyleFixed3D
    Rahmenstil (None, FixedSingle, Fixed3D)
  • Dock None
    Layout innerhalb des Parent-Containers (z.B. Fill)
  • DrawMode – Normal
    Zeichenmodus (Normal, OwnerDrawFixed, OwnerDrawVariable)
  • Enabled – $true
    Aktiviert oder deaktiviert die ListBox
  • Font Standard-Systemfont
    Schriftart der Einträge
  • ForeColor SystemColors.WindowText
    Textfarbe der Einträge
  • FormattingEnabled $true
    Aktiviert Formatierung für komplexe Objekte
  • HorizontalScrollbar $false
    Zeigt horizontale Scrollbar an
  • Location (0,0)
    Position innerhalb des Containers
  • Name ""
    Interner Name der ListBox
  • ScrollAlwaysVisible $false
    Scrollbar immer anzeigen, auch wenn nicht nötig
  • TabIndex 0
    Reihenfolge beim Durchtabben
  • TabStop $true
    Ob die ListBox per Tab erreichbar ist
  • TopIndex 0
    Index des obersten sichtbaren Elements
  • Visible $true
    Sichtbarkeit der ListBox
Items
Größe

 Image Image

Die ListBox ist eines dieser Controls, die simpel wirken, aber erstaunlich schnell chaotisch werden, wenn man sie nicht im Griff hat. Im Kern zeigt sie eine Liste von Einträgen an, aus denen der Benutzer auswählen kann.


# ListBox erstellen
$listBox = New-Object System.Windows.Forms.ListBox
$listBoxNew = [System.Windows.Forms.ListBox]::new()

# Größe & Position
$listBox.Size = New-Object System.Drawing.Size(200,150)
$listBox.Location = New-Object System.Drawing.Point(10,10)

# Items hinzufügen
$listBox.Items.Add("Apfel")
$listBox.Items.Add("Banane")
$listBox.Items.Add("Kirsche")

# Mehrere auf einmal
$listBox.Items.AddRange(@("Orange","Mango","Traube"))

📥 Werte auslesen

# Einzelne Auswahl
$selected = $listBox.SelectedItem

# Index
$index = $listBox.SelectedIndex

# Mehrere auswählen
$selectedItems = $listBox.SelectedItems
Events
  • Event – Hinweistext
    Auslöser / Trigger dieses Events

  • SelectedIndexChanged
    Wird ausgelöst, sobald sich die Auswahl ändert.
  • SelectedValueChanged
    Fast wie SelectedIndexChanged, aber subtil anders.
    Feuert, wenn sich der Value ändert (relevant bei ValueMember)

  • Click
    Löst bei jedem Klick auf das Control aus
  • DoubleClick
    Feuert, beim Doppelklick auf das Control / oder ein Item
  • MouseDown
    Feuert vor dem Click
  • MouseUp
    Feuert nach dem Click

  • KeyDown
    Wird ausgelöst, wenn eine Taste gedrückt wird
  • KeyUp
    Sowie KeyDown, aber erst wenn losgelassen wird

Events ListBox

SelectedIndexChanged

Wird ausgelöst, sobald sich die Auswahl ändert.

$listBox.Add_SelectedIndexChanged({
    Write-Host "Ausgewählt:" $listBox.SelectedItem
})

SelectedValueChanged

Fast wie SelectedIndexChanged… aber subtil anders.
Feuert, wenn sich der Value ändert (relevant bei ValueMember).

$listBox.Add_SelectedValueChanged({
    Write-Host "Value geändert:" $listBox.SelectedItem
})

👉 Unterschied merkst du erst, wenn du mit Objekten arbeitest.


Click

Wird bei jedem Klick ausgelöst.
Ja, auch wenn sich nichts ändert. Klassiker für doppelte Logik.

$listBox.Add_Click({
    Write-Host "ListBox wurde geklickt"
})

DoubleClick

Wenn der User doppelt klickt. Perfekt für „öffnen“, „starten“, etc.

$listBox.Add_DoubleClick({
    Write-Host "Doppelklick auf:" $listBox.SelectedItem
})

👉 UX-technisch oft sinnvoller als Button daneben.


KeyDown

Für Tastatursteuerung. Wird ausgelöst, wenn eine Taste gedrückt wird.

$listBox.Add_KeyDown({
    if ($_.KeyCode -eq "Enter") {
        Write-Host "Enter auf:" $listBox.SelectedItem
    }
})

👉 Das ist der Moment, wo dein UI sich plötzlich „professionell“ anfühlt.


KeyUp

Wie KeyDown, nur nachdem losgelassen wurde.

$listBox.Add_KeyUp({
    Write-Host "Taste losgelassen:" $_.KeyCode
})

MouseDown

Feuert vor Click. Gut für spezielle Logik.

$listBox.Add_MouseDown({
    Write-Host "MouseDown erkannt"
})

MouseUp

Nach dem Klick.

$listBox.Add_MouseUp({
    Write-Host "MouseUp erkannt"
})

Tipps & Tricks - TabControl

Ich sag’s dir direkt, weil ich genau weiß, wie das läuft:

Du kombinierst sowas:

Click
SelectedIndexChanged
DoubleClick

…und wunderst dich, warum dein Code mehrfach läuft.

👉 Beispiel:

→ Boom, drei Events für einen simplen Klick.


🧩 Mini-Leitfaden (der dir später Nerven spart)



➕ Items verwalten

# Entfernen
$listBox.Items.Remove("Apfel")

# Alles löschen
$listBox.Items.Clear()

# Einfügen an Position
$listBox.Items.Insert(0, "Neu")

🎨 Nützliche Tricks

Automatisch sortieren

$listBox.Sorted = $true

Mehrspaltig anzeigen

$listBox.MultiColumn = $true

Scrollbar erzwingen

$listBox.HorizontalScrollbar = $true

⚠️ Typische Stolperfallen


🧩 Best Practice


Ich greif einen Punkt raus, den du wahrscheinlich unterschätzt:

Was speicherst du eigentlich in der ListBox? Strings oder Objekte?

Wenn du nur Strings reinwirfst, verbaust du dir später jede sinnvolle Logik.
Pack lieber direkt Objekte rein:

$listBox.Items.Add([PSCustomObject]@{
    Name = "Chrome"
    Version = "123"
})

Und dann:

$listBox.DisplayMember = "Name"

Das ist der Unterschied zwischen „funktioniert irgendwie“ und „ich hab Kontrolle über meinen Code“.

Das ist so ein klassischer Punkt, wo Leute sich später selbst hassen, weil sie am Anfang “einfach schnell Strings genommen haben”.

RichTextBox

Namespace: System.Windows.Forms

Properties / Eigenschaften

Die RichTextBox ist eine erweiterte Textbox, die es ermöglicht, formatierte Textinhalte darzustellen und zu bearbeiten. Sie unterstützt RTF (Rich Text Format) sowie einfache Textformate.


Erstellen

# Erstellen
$richTextBox = New-Object System.Windows.Forms.RichTextBox
$richTextBoxNew = [System.Windows.Forms.RichTextBox]::new()

# Größe & Position
$richTextBox.Size = New-Object System.Drawing.Size(400, 200)
$richTextBox.Location = New-Object System.Drawing.Point(10,10)

# Text setzen
$richTextBox.Text = "Hallo, dies ist ein Testtext in der RichTextBox!"

# Formatierter Text (RTF)
$richTextBox.Rtf = "{\rtf1\ansi\ansicpg1252\uc1\pard\lang1031\f0\fs20 Hallo, \b dies ist ein \i Test \b0\i0 Text.\par}"

📥 Werte auslesen

# Einfacher Text
$plainText = $richTextBox.Text

# RTF-Text
$rtfText = $richTextBox.Rtf

# Auswahl
$selectedText = $richTextBox.SelectedText

👉 Unterschied:
Text gibt nur den normalen Text zurück, während Rtf den gesamten formatierten Text (inklusive Formatierung) liefert.


Events - RichTextBox

TextChanged

Wird ausgelöst, wenn sich der Text in der RichTextBox ändert.

$richTextBox.Add_TextChanged({
Write-Host "Text hat sich geändert!"
})

SelectionChanged

Wenn der Benutzer die Auswahl ändert, wird dieses Event ausgelöst.

$richTextBox.Add_SelectionChanged({
Write-Host "Neue Auswahl: $($richTextBox.SelectedText)"
})

LinkClicked

Wenn der Benutzer auf einen Link klickt, wird dieses Event ausgelöst.

$richTextBox.Add_LinkClicked({
param($sender, $e)
Write-Host "Link angeklickt: $($e.Link)"
})

Tipps & Tricks

Formatierter Text

$richTextBox.SelectionColor = "Red"
$richTextBox.SelectionFont = New-Object System.Drawing.Font("Arial", 12, [System.Drawing.FontStyle]::Bold)

$richTextBox.AppendText(" Dies ist ein Text mit roter Schrift und fettem Arial.")

RTF-Inhalt speichern

# RTF in Datei speichern
$richTextBox.SaveFile("C:\Pfad\zur\Datei.rtf", [System.Windows.Forms.RichTextBoxStreamType]::RichText)

$richTextBox.AppendText("Hier klicken: ")
$richTextBox.InsertLink("https://www.example.com")

⚠️ Typische Stolperfallen


🧩 Best Practice

TabControl

Ein TabControl ist ein Container, der mehrere TabPage-Instanzen verwaltet und zwischen ihnen umschaltet.
Es stellt die Tabs (Reiter) dar und bestimmt, welche TabPage aktuell sichtbar ist.


Grundlagen

Das TabControl ist die Steuerung, nicht der Inhalt.

TabControl erstellen

# Klassisch
$tabControl = New-Object System.Windows.Forms.TabControl

# .NET-Style
$tabControl = [System.Windows.Forms.TabControl]::new()

TabPage hinzufügen

Ein TabPage wird nicht direkt zum TabControl hinzugefügt, sondern zur enthaltenen Sammlung $tabControl.TabPages.
Die Sammlung TabPages stellt mehrere Methoden zum Hinzufügen von TabPage-Instanzen bereit:

$tabControl.TabPages.Add($tabPage1)

$tabControl.TabPages.AddRange(@(
    $tabPage2,
    $tabPage3
))

$tabControl.TabPages.Insert(0, $tabPage4)

# Technisch möglich, aber nicht empfohlen
$tabControl.Controls.Add($tabPage4)
$tabControl.Controls.AddRange(@(
    $tabPage5,
    $tabPage6
))

Über Add() kann zusätzlich direkt ein neues TabPage erstellt werden:

# Erstellt ein neues TabPage
$tabControl.TabPages.Add("TabText")

# Erstellt ein neues TabPage mit Name + Text
$tabControl.TabPages.Add("TabName", "TabText")

TabPage entfernen

Ein TabPage kann aus dem TabControl mit der Referenz zum TabPage und Remove() oder über den Index mit RemoveAt() entfernt werden.

$tabControl.TabPages.Remove($tabPage1) # mit Referenz
$tabControl.TabPages.RemoveAt(0) # mit Index

Mit Clear() werden alle TabPage-Instanzen entfernt.

# Alle entfernen
$tabControl.TabPages.Clear()

TabPage Auswahl/Zugriff

Mit dem jeweiligen Index vom TabPage, kann in TabPages direkt auf das TabPage zugegriffen werden.

# Zugriff auf einzelnes TabPage
$tabControl.TabPages[0]

# Aktiven Tab setzen
$tabControl.SelectedIndex = 0
$tabControl.SelectedTab = $tabPage1

Eigenschaften

Eigenschaften

Alignment [Systems.Windows.Forms.TabAlignment]

Der Wert von Alignment legt fest, an welcher Seite des TabControl die Tabs dargestellt werden. Standardmäßig ist diese Eigenschaft auf Top gesetzt, wodurch sich die Tabs oberhalb des Inhaltsbereichs befinden. Alternativ können die Tabs auch am unteren (Bottom), linken (Left) oder rechten (Right) Rand angezeigt werden. Die Position der Tabs beeinflusst lediglich deren Darstellung und hat keinen Einfluss auf die enthaltenen TabPage-Instanzen oder deren Funktionalität.

Anchor [Systems.Windows.Forms.AnchorStyles]

Der Wert von Anchor legt fest, an welchen Rändern seines Parent-Containers ein Control verankert ist. Standardmäßig ist diese Eigenschaft auf Top, Left gesetzt, wodurch das Control seinen Abstand zum oberen und linken Rand beibehält. Wird die Größe des Parent-Containers verändert, passt das Control seine Position oder Größe entsprechend den festgelegten Verankerungen an.

Mehrere Verankerungen können kombiniert werden. Ist ein Control beispielsweise an Left und Right verankert, wird seine Breite automatisch angepasst, um den Abstand zu beiden Rändern beizubehalten. Durch die Kombination verschiedener Werte lässt sich das Verhalten eines Controls bei Größenänderungen flexibel steuern.

Appearance [System.Windows.Forms.TabAppearance]

Der Wert von Appearance legt fest, wie die Tabs eines TabControl dargestellt werden. Standardmäßig ist diese Eigenschaft auf Normal gesetzt, wodurch die Tabs im klassischen Registerkarten-Stil angezeigt werden. Alternativ können die Tabs als Schaltflächen (Buttons) oder als flache Schaltflächen (FlatButtons) dargestellt werden.

Die Eigenschaft beeinflusst ausschließlich das Erscheinungsbild der Tabs und hat keinen Einfluss auf die Funktionalität des TabControl oder der enthaltenen TabPage-Instanzen. Unabhängig von der gewählten Darstellung können Tabs weiterhin ausgewählt und gewechselt werden.

Dock [Systems.Windows.Forms.DockStyle]

Der Wert von Dock legt fest, an welcher Seite seines Parent-Containers ein Control angedockt wird. Standardmäßig ist diese Eigenschaft auf None gesetzt, wodurch die Position und Größe des Controls ausschließlich durch dessen Location- und Size-Eigenschaften bestimmt werden. Alternativ kann das Control an den oberen (Top), unteren (Bottom), linken (Left) oder rechten (Right) Rand angedockt oder mit Fill auf die gesamte verfügbare Fläche des Parent-Containers ausgedehnt werden.

Im Gegensatz zu Anchor bestimmt Dock nicht die Abstände zu den Rändern, sondern übernimmt die automatische Positionierung und Größenanpassung des Controls. Wird beispielsweise Fill verwendet, füllt das Control den gesamten verfügbaren Bereich seines Parent-Containers aus.

DrawMode [Systems.Windows.Forms.TabDrawMode]

Der Wert von DrawMode legt fest, wie die Tabs des TabControl gezeichnet werden. Standardmäßig ist diese Eigenschaft auf Normal gesetzt, wodurch das Betriebssystem die Darstellung der Tabs vollständig übernimmt. Wird DrawMode auf OwnerDrawFixed gesetzt, ist der Entwickler für das Zeichnen der Tabs verantwortlich und kann deren Aussehen individuell gestalten.

Die Einstellung OwnerDrawFixed wird häufig verwendet, um eigene Farben, Schriftarten oder Symbole für Tabs darzustellen. Da die Tabs dabei selbst gezeichnet werden müssen, wird zusätzlich das DrawItem-Event benötigt, in dem die eigentliche Darstellung implementiert wird.

HotTrack [System.Boolean]

Der Wert von HotTrack legt fest, ob Tabs auf Mausbewegungen reagieren sollen. Standardmäßig ist diese Eigenschaft auf False gesetzt, wodurch Tabs ihr Aussehen beim Überfahren mit dem Mauszeiger nicht verändern. Wird HotTrack auf True gesetzt, hebt das TabControl den Tab unter dem Mauszeiger visuell hervor, um die Interaktion für den Benutzer deutlicher zu machen.

ImageList [Systems.Windows.Forms.ImageList]

Der Wert von ImageList legt die Bildersammlung fest, aus der die Tabs ihre Symbole beziehen. Standardmäßig ist diese Eigenschaft auf $null gesetzt, wodurch keine Symbole angezeigt werden. Die Eigenschaft dient lediglich als Quelle der verfügbaren Bilder. Welche Bilder tatsächlich in den Tab-Headern angezeigt werden, wird über die Eigenschaften ImageIndex oder ImageKey der jeweiligen TabPage festgelegt.

ItemSize [System.Drawing.Size]

Der Wert von ItemSize legt die Größe der einzelnen Tabs fest. Standardmäßig besitzt diese Eigenschaft den Wert (Width=0, Height=0), wodurch die Größe der Tabs automatisch durch das TabControl bestimmt wird. Die Eigenschaft wird erst relevant, wenn SizeMode auf Fixed gesetzt ist. In diesem Fall verwendet das TabControl die in ItemSize festgelegte Breite und Höhe für alle Tabs.

Multiline [System.Boolean]

Der Wert von Multiline legt fest, ob die Tabs auf mehrere Reihen verteilt werden dürfen. Standardmäßig ist diese Eigenschaft auf False gesetzt, wodurch alle Tabs in einer einzelnen Reihe dargestellt werden. Wird Multiline auf True gesetzt, erstellt das TabControl bei Platzmangel automatisch zusätzliche Reihen, sodass alle Tabs sichtbar bleiben können.

Padding [System.Windows.Forms.Padding]

Der Wert von Padding legt den Innenabstand innerhalb der Tab-Header fest. Standardmäßig ist diese Eigenschaft auf (6, 3) gesetzt. Dadurch wird zwischen dem Rand eines Tabs und dessen Inhalt, beispielsweise dem Text oder einem Icon, ein zusätzlicher Abstand eingefügt.

Die Eigenschaft beeinflusst nicht den Inhalt der enthaltenen TabPage-Instanzen, sondern ausschließlich die Darstellung der Tabs selbst. Durch größere Werte kann mehr Platz zwischen dem Rand eines Tabs und dessen Inhalt geschaffen werden, während kleinere Werte zu einer kompakteren Darstellung führen.

RowCount [System.Int32]

Der Wert von RowCount gibt an, aus wie vielen Reihen die Tabs aktuell bestehen. Standardmäßig beträgt der Wert 0, solange sich keine TabPage im TabControl befindet. Die Eigenschaft wird vom TabControl automatisch ermittelt und kann nicht direkt festgelegt werden. Besonders relevant ist RowCount, wenn Multiline auf True gesetzt ist, da die Tabs dann auf mehrere Reihen verteilt werden können.

SelectedImageIndex [System.Int32]

Der Wert von SelectedImageIndex legt den Index des Bildes fest, das für den aktuell ausgewählten Tab verwendet werden soll. Standardmäßig ist diese Eigenschaft auf -1 gesetzt, wodurch kein spezielles Bild für den aktiven Tab definiert ist. Die Bilder werden dabei aus der dem TabControl zugewiesenen ImageList bezogen.

Ist ein gültiger Bildindex angegeben, kann für den ausgewählten Tab ein anderes Symbol als für die übrigen Tabs dargestellt werden. Die Eigenschaft wird hauptsächlich in Verbindung mit einer ImageList verwendet und hat ohne zugewiesene Bilder keine sichtbare Auswirkung.

SelectedIndex [System.Int32]

Der Wert von SelectedIndex entspricht dem Index des aktuell aktiven TabPage. Die TabPages-Collection ist 0-basiert, weshalb das erste TabPage den Index 0 besitzt. Befindet sich mindestens ein TabPage im TabControl, ist standardmäßig das erste TabPage aktiv. Ist die TabPages-Collection leer, beträgt der Wert von SelectedIndex -1.

SelectedTab [System.Windows.Forms.TabPage]

Der Wert von SelectedTab enthält eine Referenz auf die aktuell aktive TabPage des TabControl. Standardmäßig ist diese Eigenschaft auf $null gesetzt, solange sich keine TabPage in der TabPages-Collection befindet. Sobald mindestens ein TabPage vorhanden ist, verweist SelectedTab auf das aktuell ausgewählte TabPage. Über diese Eigenschaft kann sowohl das aktive TabPage ausgelesen als auch ein anderes TabPage direkt ausgewählt werden.

ShowToolTips [System.Boolean]

Der Wert von ShowToolTips legt fest, ob für die Tabs eines TabControl Tooltips angezeigt werden dürfen. Standardmäßig ist diese Eigenschaft auf $false gesetzt, wodurch keine Tooltips dargestellt werden. Wird ShowToolTips auf $true gesetzt, können einzelnen TabPage-Instanzen Tooltip-Texte zugewiesen werden, die beim Überfahren des jeweiligen Tabs mit dem Mauszeiger angezeigt werden.

SizeMode [Systems.Windows.Forms.TabSizeMode]

Der Wert von SizeMode legt fest, wie die Größe der einzelnen Tabs bestimmt wird. Standardmäßig ist diese Eigenschaft auf Normal gesetzt, wodurch die Breite jedes Tabs automatisch anhand seines Inhalts berechnet wird. Wird SizeMode auf Fixed gesetzt, erhalten alle Tabs dieselbe Größe, die über die Eigenschaft ItemSize festgelegt werden kann.

TabPages [Systems.Windows.Forms.TabControl.TabPageCollection]

Der Wert von TabPages enthält die Sammlung aller TabPage-Instanzen, die dem TabControl hinzugefügt wurden. Standardmäßig ist diese Sammlung leer. Über TabPages können TabPage-Instanzen hinzugefügt, entfernt oder anhand ihres Indexes bzw. ihrer Referenz abgerufen werden. Die Reihenfolge der Elemente innerhalb der Sammlung entspricht dabei der Reihenfolge der Tabs im TabControl.


Methoden

Methoden
TabControl
TabControl.TabPages

TabControl

GetTabRect()

Datentyp: [System.Drawing.Rectangle]
Rückgabewert:
  Position und Größe des Tab-Headers

GetTabRect( Index )

Die Methode GetTabRect() gibt die Position und Größe eines Tabs innerhalb des TabControl zurück.
Über den angegebenen Index wird festgelegt, für welchen Tab die Informationen ermittelt werden sollen. Der Rückgabewert ist ein Rectangle, das die Position sowie die Breite und Höhe des entsprechenden Tab-Headers enthält. Die zurückgegebenen Koordinaten beziehen sich auf das TabControl selbst.

Die Methode wird häufig verwendet, um Mausklicks auf einzelne Tabs zu erkennen oder um eigene Zeichnungslogik mit OwnerDrawFixed umzusetzen.


TabControl.TabPages

Add()

$_.TabPages.Add( $tabPage )
# → vorhandenes TabPage hinzufügen

Die Methode Add() fügt eine TabPage zur TabPages-Collection hinzu. Das TabPage wird dabei am Ende der Sammlung eingefügt und erscheint als neuer Tab im TabControl.

Nach dem Hinzufügen kann das TabPage über die TabPages-Collection, SelectedIndex oder SelectedTab verwendet werden.

$_.TabPages.Add( "Text" )
# → Neues TabPage mit Text erstellen

Der übergebene Text wird dabei als Beschriftung des Tabs verwendet. 

$_.TabPages.Add( "Name", "Text" )
# → Neues TabPage mit Name und Text erstellen

Hierbei wird sowohl der interne Name als auch die sichtbare Beschriftung (Text) festgelegt.

Diese Varianten eignen sich für einfache Tabs, bei denen keine weiteren Eigenschaften unmittelbar gesetzt werden müssen.

AddRange()

$_.TabPages.AddRange( $tabPages )

Die Methode AddRange() fügt mehrere TabPage-Instanzen gleichzeitig zur TabPages-Collection hinzu.

Die Reihenfolge der Elemente im Array entspricht anschließend der Reihenfolge der Tabs im TabControl. Die Tabs werden dabei am Ende der vorhandenen Sammlung eingefügt.

Clear()

$_.TabPages.Clear()

Die Methode Clear() entfernt alle TabPage-Instanzen aus der TabPages-Collection.

Nach dem Aufruf enthält das TabControl keine Tabs mehr. Existiert kein Tab mehr, besitzen Eigenschaften wie SelectedIndex den Wert -1 und SelectedTab den Wert $null.

Insert()

$_.TabPages.Insert( Index, $tabPage )

Die Methode Insert() fügt eine TabPage an einer bestimmten Position innerhalb der TabPages-Collection ein.

Bereits vorhandene Einträge werden ab dieser Position um eine Stelle nach hinten verschoben. Dadurch kann die Reihenfolge der Tabs gezielt beeinflusst werden.

Remove()

$_.TabPages.Remove( $tabPage )

Die Methode Remove() entfernt eine bestimmte TabPage aus der TabPages-Collection.

Das TabPage selbst wird dabei nicht gelöscht, sondern lediglich aus dem TabControl entfernt. Es kann später erneut einer TabPages-Collection hinzugefügt werden.

RemoveAt()

$_.TabPages.RemoveAt( Index )

Die Methode RemoveAt() entfernt die TabPage an der angegebenen Position aus der TabPages-Collection.

Die verbleibenden Einträge rücken anschließend entsprechend nach vorne auf. Dadurch können sich die Indizes nachfolgender TabPages ändern.



Events

Events
$tabControl.Add_*
  param($sender, $e)

Tabwechsel

Selecting

Vor dem Wechsel zu einem Tab (TabPage) → kann noch abgebrochen werden

Selected

Nach dem Wechsel zu einem Tab (TabPage)

$tabControl.Add_Selecting({
    param($sender, $e)

    # Ziel-Tab
    $nextTab = $e.TabPage

    if ($nextTab.Name -eq "PackageTab") {
        Write-Host "Wechsel verhindert!"

        # 🚨 DAS ist der Trick:
        $e.Cancel = $true
    }
})

SelectedIndexChanged

Wird ausgelöst, nachdem sich der ausgewählte Tab geändert hat

$sender, $e

$sender

$e

$tabControl.Add_SelectedIndexChanged({
    param($sender, $e)

    # Aktueller Tab
    $currentTab = $sender.SelectedTab

    Write-Host "Aktiver Tab: $($currentTab.Name)"
})

Deselecting

Vor dem Verlassen eines Tabs (TabPage) → kann noch abgebrochen werden

$tabControl.Add_Deselecting({
    param($sender, $e)

    # Aktueller Tab (der verlassen wird)
    $currentTab = $e.TabPage

    # Beispiel: Verhindere Verlassen wenn noch Auswahl vorhanden
    if ($currentTab.Name -eq "PackageTab" -and $checkedListBox.CheckedItems.Count -gt 0) {
        Write-Host "Du hast noch Auswahl!"

        $e.Cancel = $true
    }
})

$e (EventArgs)
$e.TabPage → der Tab, der verlassen wird
$e.Cancel$true = Wechsel wird verhindert

Deselected

Nach dem Verlassen eines Tabs → ideal zum Zurücksetzen von UI

$tabControl.Add_Deselected({
    param($sender, $e)

    # Verlassener Tab
    $oldTab = $e.TabPage

    if ($oldTab.Name -eq "PackageTab") {

        # CheckedListBox zurücksetzen
        for ($i = 0; $i -lt $checkedListBox.Items.Count; $i++) {
            $checkedListBox.SetItemChecked($i, $false)
        }

        # ListBox zurücksetzen
        $listBox.ClearSelected()
    }
})

$e (EventArgs)
$e.TabPage → der Tab, der verlassen wurde

🔍 Konkreter Ablauf beim Tabwechsel

Wenn du von Tab A → Tab B wechselst:

  1. Deselecting (TabControl)
    → bevor Tab A verlassen wird
    kann abgebrochen werden ($_.Cancel = $true)
  2. Selecting (TabControl)
    → bevor Tab B aktiviert wird
    kann ebenfalls abgebrochen werden

👉 Wenn hier keiner abbricht, geht’s weiter:

  1. Deselected (TabControl)
    → Tab A wurde gerade deaktiviert
  2. SelectedIndexChanged (TabControl)
    → der Index hat sich geändert
  3. Selected (TabControl)
    → Tab B ist jetzt aktiv
  4. Leave (TabPage A)
    → Fokus verlässt alten Tab
  5. Enter (TabPage B)
    → Fokus betritt neuen Tab

Click

Klick auf das Control (selten relevant)

MouseDown

Klick einer beliebigen Maustaste auf dem TabControl


ControlAdded / ControlRemoved

Wenn TabPages hinzugefügt oder entfernt werden. Wird ausgelöst, wenn ein TabPage zur TabPages-Collection
hinzugefügt oder daraus entfernt wird.


Tipps & Tricks - TabControl


Typische Stolperfallen


Mentales Modell

Das TabControl ist ein Container mit Umschalter-Logik.

Es zeigt genau eine TabPage gleichzeitig
und verwaltet nur, welche sichtbar ist.


Wann sinnvoll?


Wann vermeiden?


TableLayoutPanel

1. Grid-Struktur
Ein TableLayoutPanel ist im Kern ein dynamisches Raster aus:

Die Styles bestimmen wie der Platz verteilt wird, nicht nur wie viele Zellen existieren.

TabPage

Eine TabPage ist im Grunde eine einzelne Seite innerhalb eines TabControl.
Sie stellt den Inhalt dar, der angezeigt wird, wenn ein bestimmter Tab ausgewählt ist.

Eigenschaften

Beispiel Eigenschaft



Grundidee

Ein TabControl ist der Container für die jeweiligen TabPage-Instanzen.
TabPage beinhaltet den sichtbaren Inhalt und TabControl ist das möglichmachende Gerüst.


Beispiel (PowerShell)

$tabControl = [System.Windows.Forms.TabControl]::New()

# Erstellen
$tabPage1 = New-Object System.Windows.Forms.TabPage
$tabPage2 = [System.Windows.Forms.TabPage]::New()

# Hinzufügen
$tabControl.TabPages.Add($tabPage2) # TabPage → TabControl

# Erstellen & Hinzufügen
$tabControl.TabPages.Add("Dritter Tab") # Text = "Dritter Tab"
$tabControl.TabPages.Add("tabPage4", "Vierter Tab") # Name = "tabPage4", Text = "Vierter Tab"

Controls hinzufügen

$button = New-Object System.Windows.Forms.Button
$button.Text = "Klick mich"

$tabPage1.Controls.Add($button)

Wichtig:
Controls werden immer direkt zur TabPage hinzugefügt, nicht zum TabControl.


Tab wechseln (programmatisch)

$tabControl.SelectedTab = $tabPage2

oder

$tabControl.SelectedIndex = 1

Events

TabPage selbst hat keine super-spezifischen Events wie das TabControl.
Sie verhält sich eher wie ein normales Panel.

Trotzdem gibt es ein paar relevante:


Wichtig: Tab-Wechsel-Events liegen am TabControl

Wenn du wirklich auf Tab-Wechsel reagieren willst, bist du hier falsch unterwegs:

Die gehören zum TabControl, nicht zur TabPage.

Das ist einer dieser klassischen Momente, wo WinForms dich still verarscht.


Typische Stolperfallen


Mentales Modell

Denk nicht in "Tabs".
Denk in Panels mit Umschalter.

Jede TabPage ist einfach ein eigenes Panel.
Das TabControl entscheidet nur, welches sichtbar ist.


Wann sinnvoll?


Wann vermeiden?


GroupBox

Eine GroupBox ist ein Container zur visuellen Gruppierung von Controls.
Sie dient hauptsächlich dazu, zusammengehörige Eingabefelder, Optionen oder Steuerelemente optisch voneinander abzugrenzen.

Der Text der GroupBox wird als Überschrift im Rahmen dargestellt


Basics

Das GroupBox selbst enthält keine besondere Logik.

GroupBox erstellen

# Klassisch
$groupBox = New-Object System.Windows.Forms.GroupBox

# .NET-Style
$groupBox = [System.Windows.Forms.GroupBox]::new()

Controls hinzufügen

Controls werden über die Controls-Collection hinzugefügt.

$groupBox.Controls.Add($textBox)

$groupBox.Controls.AddRange(@(
    $label,
    $button
))

Controls entfernen

$groupBox.Controls.Remove($textBox)

$groupBox.Controls.Clear()

Eigenschaften

Eigenschaften / Propertys

Text [System.String]

Der Wert von Text bestimmt die Beschriftung der GroupBox.

Standardmäßig ist der Wert leer.

$groupBox.Text = "Office Installation"

Controls [System.Windows.Forms.Control.ControlCollection]

Enthält alle Controls, die sich innerhalb der GroupBox befinden.

$groupBox.Controls.Add($button)

Enabled [System.Boolean]

Legt fest, ob die GroupBox aktiviert ist.

Wird Enabled auf $false gesetzt, werden auch alle enthaltenen Controls deaktiviert.

$groupBox.Enabled = $false

Padding [System.Windows.Forms.Padding]

Legt den Innenabstand fest, der zwischen Rahmen und enthaltenen Controls eingehalten wird.

$groupBox.Padding = 10

Methoden

GroupBox.Controls

Methoden – Controls

Add()

$_.Controls.Add($control)

Die Methode Add() fügt ein Control zur Controls-Collection der GroupBox hinzu.

AddRange()

$_.Controls.AddRange(@(
    $label,
    $textbox,
    $button
))

Die Methode AddRange() fügt mehrere Controls gleichzeitig zur Controls-Collection hinzu.

Remove()

$_.Controls.Remove($control)

Die Methode Remove() entfernt ein bestimmtes Control aus der GroupBox.

Clear()

$_.Controls.Clear()

Die Methode Clear() entfernt alle enthaltenen Controls.


Events

Events
$groupBox.Add_*({
    param($sender, $e)
})

ControlAdded / ControlRemoved

Werden ausgelöst, wenn Controls zur Controls-Collection hinzugefügt oder daraus entfernt werden.

$groupBox.Add_ControlAdded({
    param($sender, $e)

    Write-Host "$($e.Control.Name) wurde hinzugefügt"
})

Tipps & Tricks

Typische Stolperfallen


Mentales Modell

Die GroupBox ist ein Container mit Beschriftung.

Sie gruppiert Controls optisch und logisch, besitzt jedoch keine eigene Inhaltslogik.


Wann sinnvoll?


Wann vermeiden?