# Form

# Form

Ein `Form` ist das **Fenster einer Windows-Forms-Anwendung**. Es dient als oberster Container für Controls wie `Panel`, `Button`, `Label`, `TextBox`, `TabControl` oder `TableLayoutPanel`.

Ein `Form` kann sowohl als **Hauptfenster einer Anwendung** als auch als **Dialogfenster** verwendet werden.

---

## Grundlagen

Ein `Form` stellt die sichtbare Oberfläche einer Windows-Forms-Anwendung dar.

Typischer Aufbau:

```text
Form
├── Panel
│   ├── Label
│   └── Button
├── TabControl
│   ├── TabPage
│   └── TabPage
└── TableLayoutPanel
```

Controls werden über die `Controls`-Collection des Formulars hinzugefügt:

```powershell
$form.Controls.Add($button)
```

Das entspricht dem grundlegenden Aufbau der anderen Windows-Forms-Controls, die ebenfalls über eine `Controls`-Collection miteinander verschachtelt werden. 

---

## Form erstellen

### Klassisch

```powershell
$form = New-Object System.Windows.Forms.Form
```

### .NET-Style

```powershell
$form = [System.Windows.Forms.Form]::new()
```

Anschließend können Eigenschaften gesetzt und Controls hinzugefügt werden:

```powershell
$form = [System.Windows.Forms.Form]::new()

$form.Text = "Meine Anwendung"
$form.Size = "800, 600"

$button = [System.Windows.Forms.Button]::new()
$button.Text = "OK"

$form.Controls.Add($button)
```

---

## Formular anzeigen

### Nicht modal

Mit `Show()` wird das Formular angezeigt, ohne den aufrufenden Code zu blockieren.

```powershell
$form.Show()
```

Das Formular bleibt geöffnet, während das PowerShell-Skript weiter ausgeführt wird.

### Modal

Mit `ShowDialog()` wird das Formular als modales Fenster geöffnet.

```powershell
$result = $form.ShowDialog()
```

Der aufrufende Code wartet, bis das Formular geschlossen wird.

Besonders bei Dialogfenstern ist `ShowDialog()` interessant, da über `DialogResult` ein Ergebnis zurückgegeben werden kann. Dieses Prinzip wird beispielsweise auch bei Buttons verwendet. 

---

# Eigenschaften

| Eigenschaft       | Standardwert                 | Beschreibung                                                               |
| ----------------- | ---------------------------- | -------------------------------------------------------------------------- |
| `AcceptButton`    | `$null`                      | Legt den Button fest, der bei Betätigung der Enter-Taste ausgelöst wird.   |
| `AutoScaleMode`   | `Font`                       | Bestimmt, anhand welcher Grundlage das Formular automatisch skaliert wird. |
| `AutoScroll`      | `False`                      | Aktiviert automatische Scrollleisten für übergroße Inhalte.                |
| `BackColor`       | `Control`                    | Legt die Hintergrundfarbe des Formulars fest.                              |
| `BackgroundImage` | `$null`                      | Legt ein Hintergrundbild fest.                                             |
| `CancelButton`    | `$null`                      | Legt den Button fest, der bei Betätigung der Escape-Taste ausgelöst wird.  |
| `ClientSize`      | abhängig vom Standard-Layout | Legt die Größe des nutzbaren Inhaltsbereichs fest.                         |
| `ControlBox`      | `True`                       | Bestimmt, ob die Schaltflächen der Titelleiste angezeigt werden.           |
| `Cursor`          | `Default`                    | Legt den Mauszeiger innerhalb des Formulars fest.                          |
| `FormBorderStyle` | `Sizable`                    | Bestimmt die Art des Fensterrahmens.                                       |
| `Icon`            | Standardicon                 | Legt das Symbol des Fensters fest.                                         |
| `KeyPreview`      | `False`                      | Bestimmt, ob das Formular Tastatureingaben vor seinen Controls erhält.     |
| `Location`        | abhängig vom System          | Bestimmt die Position des Fensters auf dem Bildschirm.                     |
| `MaximizeBox`     | `True`                       | Legt fest, ob das Fenster maximiert werden kann.                           |
| `MaximumSize`     | `(0,0)`                      | Definiert die maximal zulässige Fenstergröße.                              |
| `MinimizeBox`     | `True`                       | Legt fest, ob das Fenster minimiert werden kann.                           |
| `MinimumSize`     | `(0,0)`                      | Definiert die minimal zulässige Fenstergröße.                              |
| `Name`            | `""`                         | Legt den internen Namen des Formulars fest.                                |
| `Opacity`         | `1.0`                        | Bestimmt die Transparenz des Fensters.                                     |
| `Padding`         | `0,0,0,0`                    | Legt den Innenabstand zwischen Fensterrahmen und Inhalt fest.              |
| `ShowIcon`        | `True`                       | Bestimmt, ob das Fenstersymbol angezeigt wird.                             |
| `ShowInTaskbar`   | `True`                       | Bestimmt, ob das Fenster in der Taskleiste erscheint.                      |
| `Size`            | abhängig vom System          | Bestimmt Breite und Höhe des Fensters.                                     |
| `StartPosition`   | `WindowsDefaultLocation`     | Bestimmt die Position beim ersten Anzeigen des Fensters.                   |
| `Text`            | `""`                         | Legt den Text in der Titelleiste fest.                                     |
| `TopMost`         | `False`                      | Legt fest, ob das Fenster immer über anderen Fenstern bleibt.              |
| `WindowState`     | `Normal`                     | Bestimmt den aktuellen Zustand des Fensters.                               |

---

<details>
<summary>AcceptButton</summary>

### **AcceptButton**

**Typ** = `[System.Windows.Forms.IButtonControl]`

`AcceptButton` legt fest, welcher Button ausgelöst wird, wenn der Benutzer innerhalb des Formulars die **Enter-Taste** betätigt.

```powershell
$form.AcceptButton = $okButton
```

Dies ist besonders bei Dialogfenstern praktisch:

```powershell
$okButton = [System.Windows.Forms.Button]::new()
$okButton.Text = "OK"

$form.AcceptButton = $okButton
$form.Controls.Add($okButton)
```

Der Benutzer kann dadurch beispielsweise ein Formular mit Enter bestätigen, ohne den Button mit der Maus anzuklicken.

</details>

---

<details>
<summary>AutoScaleMode</summary>

### **AutoScaleMode**

**Typ** = `[System.Windows.Forms.AutoScaleMode]`

`AutoScaleMode` bestimmt, anhand welcher Grundlage das Formular und seine Controls automatisch skaliert werden.

Typische Werte sind:

* `None` → keine automatische Skalierung
* `Font` → Skalierung anhand der Schriftgröße
* `Dpi` → Skalierung anhand der DPI-Einstellung
* `Inherit` → übernimmt die Einstellung des übergeordneten Controls

```powershell
$form.AutoScaleMode = "Font"
```

Gerade bei unterschiedlichen Windows-Skalierungseinstellungen kann diese Eigenschaft wichtig sein, damit die Oberfläche nicht plötzlich aussieht, als hätte Windows sie durch einen Briefkastenschlitz geschoben.

</details>

---

<details>
<summary>AutoScroll</summary>

### **AutoScroll**

**Typ** = `[System.Boolean]`

`AutoScroll` aktiviert automatische Scrollleisten, wenn der Inhalt des Formulars größer als dessen sichtbarer Bereich ist.

**Standardwert** = `False`

```powershell
$form.AutoScroll = $true
```

Die Eigenschaft ist besonders bei Formularen mit dynamisch erzeugten oder umfangreichen Controls hilfreich.

</details>

---

<details>
<summary>BackColor</summary>

### **BackColor**

**Typ** = `[System.Drawing.Color]`

`BackColor` legt die Hintergrundfarbe des Formulars fest.

```powershell
$form.BackColor = "White"
```

</details>

---

<details>
<summary>BackgroundImage</summary>

### **BackgroundImage**

**Typ** = `[System.Drawing.Image]`

`BackgroundImage` legt ein Bild fest, das als Hintergrund des Formulars dargestellt wird.

```powershell
$form.BackgroundImage = [System.Drawing.Image]::FromFile(
    "C:\Images\background.png"
)
```

Die Darstellung des Bildes kann zusätzlich über `BackgroundImageLayout` beeinflusst werden.

</details>

---

<details>
<summary>CancelButton</summary>

### **CancelButton**

**Typ** = `[System.Windows.Forms.IButtonControl]`

`CancelButton` legt fest, welcher Button ausgelöst wird, wenn der Benutzer die **Escape-Taste** betätigt.

```powershell
$form.CancelButton = $cancelButton
```

Typischerweise wird hier ein Abbrechen-Button hinterlegt.

```powershell
$cancelButton.DialogResult = "Cancel"

$form.CancelButton = $cancelButton
```

Bei einem Dialogfenster kann dadurch die Escape-Taste zum Abbrechen verwendet werden.

</details>

---

<details>
<summary>ClientSize</summary>

### **ClientSize**

**Typ** = `[System.Drawing.Size]`

`ClientSize` bestimmt die Größe des **nutzbaren Inhaltsbereichs** des Formulars.

Im Gegensatz zu `Size` berücksichtigt `ClientSize` nicht den Fensterrahmen und die Titelleiste.

```powershell
$form.ClientSize = "800, 500"
```

Das ist insbesondere bei Layoutberechnungen interessant, wenn die Größe des eigentlichen Inhaltsbereichs relevant ist.

In deinem Windows-Setup-Helper verwendest du beispielsweise `ClientSize`, um die Formulargröße abhängig von der ausgewählten `TabPage` anzupassen. 

</details>

---

<details>
<summary>ControlBox</summary>

### **ControlBox**

**Typ** = `[System.Boolean]`

`ControlBox` bestimmt, ob die Steuerelemente der Titelleiste angezeigt werden.

**Standardwert** = `True`

```powershell
$form.ControlBox = $false
```

Bei deaktivierter `ControlBox` werden die entsprechenden Fenster-Schaltflächen wie Schließen, Minimieren und Maximieren nicht mehr auf normale Weise dargestellt.

</details>

---

<details>
<summary>FormBorderStyle</summary>

### **FormBorderStyle**

**Typ** = `[System.Windows.Forms.FormBorderStyle]`

`FormBorderStyle` bestimmt die Art des Fensterrahmens und damit unter anderem, ob der Benutzer die Größe des Fensters verändern kann.

Typische Werte:

| Wert                | Beschreibung                       |
| ------------------- | ---------------------------------- |
| `None`              | Kein Fensterrahmen                 |
| `FixedSingle`       | Fester einfacher Rahmen            |
| `Fixed3D`           | Fester 3D-Rahmen                   |
| `FixedDialog`       | Fester Dialograhmen                |
| `Sizable`           | Fenstergröße kann verändert werden |
| `FixedToolWindow`   | Festes Werkzeugfenster             |
| `SizableToolWindow` | Veränderbares Werkzeugfenster      |

```powershell
$form.FormBorderStyle = "FixedDialog"
```

Für normale Hauptfenster ist `Sizable` üblich.

</details>

---

<details>
<summary>Icon</summary>

### **Icon**

**Typ** = `[System.Drawing.Icon]`

`Icon` legt das Symbol des Formulars fest.

```powershell
$form.Icon = [System.Drawing.Icon]::ExtractAssociatedIcon(
    "C:\Program Files\App\App.exe"
)
```

Das Icon kann unter anderem in der Titelleiste und Taskleiste angezeigt werden.

</details>

---

<details>
<summary>KeyPreview</summary>

### **KeyPreview**

**Typ** = `[System.Boolean]`

`KeyPreview` bestimmt, ob das Formular Tastatureingaben **vor den enthaltenen Controls** erhält.

**Standardwert** = `False`

```powershell
$form.KeyPreview = $true
```

Dadurch können beispielsweise globale Tastenkombinationen auf Formularebene behandelt werden.

```powershell
$form.Add_KeyDown({
    param($sender, $e)

    if ($e.KeyCode -eq "F5") {
        Write-Host "F5 gedrückt"
    }
})
```

Ohne `KeyPreview` kann ein fokussiertes Control die Tastatureingabe zuerst verarbeiten.

</details>

---

<details>
<summary>Location</summary>

### **Location**

**Typ** = `[System.Drawing.Point]`

`Location` legt die Position des Formulars auf dem Bildschirm fest.

```powershell
$form.Location = "100, 100"
```

Die beiden Werte entsprechen:

```text
X = 100
Y = 100
```

Die Startposition kann alternativ über `StartPosition` automatisch bestimmt werden.

</details>

---

<details>
<summary>MaximizeBox</summary>

### **MaximizeBox**

**Typ** = `[System.Boolean]`

`MaximizeBox` bestimmt, ob das Fenster über die Titelleiste maximiert werden kann.

**Standardwert** = `True`

```powershell
$form.MaximizeBox = $false
```

Bei Dialogfenstern wird die Maximierung häufig deaktiviert.

</details>

---

<details>
<summary>MaximumSize</summary>

### **MaximumSize**

**Typ** = `[System.Drawing.Size]`

`MaximumSize` legt die maximal zulässige Größe des Formulars fest.

**Standardwert** = `(0,0)`

Der Wert `(0,0)` bedeutet, dass keine maximale Größe festgelegt wurde.

```powershell
$form.MaximumSize = "1200, 800"
```

</details>

---

<details>
<summary>MinimizeBox</summary>

### **MinimizeBox**

**Typ** = `[System.Boolean]`

`MinimizeBox` bestimmt, ob das Fenster über die Titelleiste minimiert werden kann.

**Standardwert** = `True`

```powershell
$form.MinimizeBox = $false
```

</details>

---

<details>
<summary>MinimumSize</summary>

### **MinimumSize**

**Typ** = `[System.Drawing.Size]`

`MinimumSize` legt die minimal zulässige Größe des Formulars fest.

**Standardwert** = `(0,0)`

```powershell
$form.MinimumSize = "600, 400"
```

Damit kann verhindert werden, dass der Benutzer das Fenster so weit verkleinert, dass Controls nicht mehr sinnvoll dargestellt werden.

</details>

---

<details>
<summary>Name</summary>

### **Name**

**Typ** = `[System.String]`

`Name` legt den internen Namen des Formulars fest.

```powershell
$form.Name = "MainForm"
```

Der Name dient der Identifikation innerhalb des Programms und wird dem Benutzer nicht angezeigt.

</details>

---

<details>
<summary>Opacity</summary>

### **Opacity**

**Typ** = `[System.Double]`

`Opacity` bestimmt die Deckkraft des Fensters.

Der Wertebereich liegt zwischen `0` und `1`.

|  Wert | Darstellung             |
| ----: | ----------------------- |
|   `0` | vollständig transparent |
| `0.5` | 50 % Deckkraft          |
|   `1` | vollständig sichtbar    |

```powershell
$form.Opacity = 0.8
```

**Standardwert** = `1`

</details>

---

<details>
<summary>Padding</summary>

### **Padding**

**Typ** = `[System.Windows.Forms.Padding]`

`Padding` legt den Innenabstand zwischen dem Rand des Formulars und dessen Inhalt fest.

```powershell
$form.Padding = [System.Windows.Forms.Padding]::new(10)
```

Der Wert wird insbesondere beim Layout der enthaltenen Controls berücksichtigt.

</details>

---

<details>
<summary>ShowIcon</summary>

### **ShowIcon**

**Typ** = `[System.Boolean]`

`ShowIcon` bestimmt, ob das Icon des Formulars in der Titelleiste angezeigt wird.

**Standardwert** = `True`

```powershell
$form.ShowIcon = $false
```

</details>

---

<details>
<summary>ShowInTaskbar</summary>

### **ShowInTaskbar**

**Typ** = `[System.Boolean]`

`ShowInTaskbar` bestimmt, ob das Formular als eigenes Fenster in der Windows-Taskleiste erscheint.

**Standardwert** = `True`

```powershell
$form.ShowInTaskbar = $false
```

Dies kann beispielsweise bei Hilfs- oder Dialogfenstern sinnvoll sein.

</details>

---

<details>
<summary>Size</summary>

### **Size**

**Typ** = `[System.Drawing.Size]`

`Size` bestimmt die gesamte Größe des Formulars einschließlich Fensterrahmen und Titelleiste.

```powershell
$form.Size = "800, 600"
```

Für die Größe des reinen Inhaltsbereichs sollte stattdessen `ClientSize` verwendet werden.

</details>

---

<details>
<summary>StartPosition</summary>

### **StartPosition**

**Typ** = `[System.Windows.Forms.FormStartPosition]`

`StartPosition` bestimmt, wo das Formular beim ersten Anzeigen positioniert wird.

Typische Werte:

| Wert                     | Beschreibung                                 |
| ------------------------ | -------------------------------------------- |
| `Manual`                 | Position wird über `Location` bestimmt       |
| `CenterScreen`           | Zentriert auf dem Bildschirm                 |
| `WindowsDefaultLocation` | Windows bestimmt die Position                |
| `WindowsDefaultBounds`   | Windows bestimmt Position und Größe          |
| `CenterParent`           | Zentriert relativ zum übergeordneten Fenster |

Beispiel:

```powershell
$form.StartPosition = "CenterScreen"
```

Für Dialogfenster ist häufig `CenterParent` sinnvoll.

</details>

---

<details>
<summary>Text</summary>

### **Text**

**Typ** = `[System.String]`

`Text` bestimmt den Text in der Titelleiste des Formulars.

**Standardwert** = `""`

```powershell
$form.Text = "Meine Anwendung"
```

In deinem Windows-Setup-Helper wird der Titel beispielsweise beim `Load`-Event dynamisch erweitert. 

</details>

---

<details>
<summary>TopMost</summary>

### **TopMost**

**Typ** = `[System.Boolean]`

`TopMost` bestimmt, ob das Formular dauerhaft über anderen normalen Fenstern angezeigt wird.

**Standardwert** = `False`

```powershell
$form.TopMost = $true
```

Ein `TopMost`-Fenster bleibt über normalen Fenstern, auch wenn diese den Fokus erhalten.

</details>

---

<details>
<summary>WindowState</summary>

### **WindowState**

**Typ** = `[System.Windows.Forms.FormWindowState]`

`WindowState` bestimmt den aktuellen Zustand des Formulars.

Mögliche Werte:

| Wert        | Beschreibung               |
| ----------- | -------------------------- |
| `Normal`    | Normale Fensterdarstellung |
| `Minimized` | Minimiert                  |
| `Maximized` | Maximiert                  |

```powershell
$form.WindowState = "Maximized"
```

Der Standardwert ist:

```text
Normal
```

</details>

---

# Methoden

| Methode            | Beschreibung                                                 |
| ------------------ | ------------------------------------------------------------ |
| `Show()`           | Zeigt das Formular nicht modal an.                           |
| `ShowDialog()`     | Zeigt das Formular modal an und wartet auf dessen Schließen. |
| `Close()`          | Schließt das Formular.                                       |
| `Hide()`           | Versteckt das Formular, ohne es zu schließen.                |
| `Activate()`       | Aktiviert das Formular und bringt es in den Vordergrund.     |
| `CenterToScreen()` | Zentriert das Formular auf dem Bildschirm.                   |
| `CenterToParent()` | Zentriert das Formular relativ zum Parent-Fenster.           |
| `Refresh()`        | Erzwingt eine Aktualisierung der Darstellung.                |
| `Focus()`          | Versucht, den Tastaturfokus auf das Formular zu setzen.      |
| `Dispose()`        | Gibt die vom Formular verwendeten Ressourcen frei.           |

---

<details>
<summary>Show()</summary>

### **Show()**

```powershell
$form.Show()
```

Zeigt das Formular an, ohne den aufrufenden Code zu blockieren.

Das Skript kann nach dem Aufruf weiterarbeiten.

</details>

---

<details>
<summary>ShowDialog()</summary>

### **ShowDialog()**

```powershell
$result = $form.ShowDialog()
```

Zeigt das Formular als **modales Fenster** an.

Der aufrufende Code wird angehalten, bis das Formular geschlossen wird.

Der Rückgabewert ist ein `[System.Windows.Forms.DialogResult]`.

```powershell
$result = $form.ShowDialog()

if ($result -eq "OK") {
    Write-Host "Bestätigt"
}
```

Zusammen mit `AcceptButton`, `CancelButton` und `DialogResult` lassen sich damit klassische Dialogfenster aufbauen.

</details>

---

<details>
<summary>Close()</summary>

### **Close()**

```powershell
$form.Close()
```

Schließt das Formular.

Bei einem Hauptformular kann das Schließen außerdem dazu führen, dass die Anwendung beendet wird, abhängig davon, wie die Windows-Forms-Anwendung gestartet wurde.

</details>

---

<details>
<summary>Hide()</summary>

### **Hide()**

```powershell
$form.Hide()
```

Versteckt das Formular, ohne es zu zerstören.

Das Formular kann anschließend erneut mit `Show()` angezeigt werden.

```powershell
$form.Hide()

# später
$form.Show()
```

Im Gegensatz zu `Close()` bleibt das Formular dabei bestehen.

</details>

---

<details>
<summary>Activate()</summary>

### **Activate()**

```powershell
$form.Activate()
```

Aktiviert das Formular und versucht, es in den Vordergrund zu bringen.

Dies kann beispielsweise verwendet werden, wenn ein bereits geöffnetes Fenster erneut angezeigt werden soll.

</details>

---

<details>
<summary>CenterToScreen()</summary>

### **CenterToScreen()**

```powershell
$form.CenterToScreen()
```

Positioniert das Formular in der Mitte des Bildschirms.

Alternativ kann bereits beim Start festgelegt werden:

```powershell
$form.StartPosition = "CenterScreen"
```

</details>

---

<details>
<summary>CenterToParent()</summary>

### **CenterToParent()**

```powershell
$form.CenterToParent()
```

Zentriert das Formular relativ zu seinem übergeordneten Fenster.

Dies ist insbesondere für Dialogfenster sinnvoll.

</details>

---

<details>
<summary>Dispose()</summary>

### **Dispose()**

```powershell
$form.Dispose()
```

Gibt die vom Formular verwendeten Ressourcen frei.

Nach `Dispose()` sollte das Formular nicht weiterverwendet werden.

In deinem Setup-Helper wird beispielsweise das aktuelle Formular über `Dispose()` geschlossen und freigegeben, bevor der Prozess anschließend neu gestartet wird. 

</details>

---

# Events

Ein `Form` besitzt eine große Anzahl an Events. Besonders häufig werden folgende verwendet:

| Event         | Beschreibung                                                   |
| ------------- | -------------------------------------------------------------- |
| `Load`        | Wird ausgelöst, wenn das Formular geladen wird.                |
| `Shown`       | Wird ausgelöst, nachdem das Formular erstmals angezeigt wurde. |
| `FormClosing` | Wird unmittelbar vor dem Schließen ausgelöst.                  |
| `FormClosed`  | Wird nach dem Schließen ausgelöst.                             |
| `Resize`      | Wird bei einer Größenänderung ausgelöst.                       |
| `SizeChanged` | Wird ausgelöst, wenn sich `Size` ändert.                       |
| `KeyDown`     | Wird beim Drücken einer Taste ausgelöst.                       |
| `KeyUp`       | Wird beim Loslassen einer Taste ausgelöst.                     |
| `KeyPress`    | Wird bei einer Zeichen-Tastatureingabe ausgelöst.              |
| `Activated`   | Wird ausgelöst, wenn das Formular aktiviert wird.              |
| `Deactivate`  | Wird ausgelöst, wenn das Formular den Fokus verliert.          |
| `Move`        | Wird beim Verschieben des Formulars ausgelöst.                 |

Beispiel:

```powershell
$form.Add_Load({
    Write-Host "Formular geladen"
})

$form.Add_Shown({
    Write-Host "Formular angezeigt"
})

$form.Add_FormClosed({
    Write-Host "Formular geschlossen"
})
```

In deinem eigenen Code verwendest du beispielsweise `FormClosed`, `Load`, `Resize` und `Shown` für unterschiedliche Initialisierungs- und Lebenszyklusaufgaben. 

---

## Typischer Aufbau

Ein einfaches Formular mit Button kann beispielsweise so aussehen:

```powershell
Add-Type -AssemblyName System.Windows.Forms

$form = [System.Windows.Forms.Form]::new()
$form.Text = "Meine Anwendung"
$form.ClientSize = "500, 300"
$form.StartPosition = "CenterScreen"

$button = [System.Windows.Forms.Button]::new()
$button.Text = "Schließen"
$button.Size = "120, 35"
$button.Location = "190, 130"

$button.Add_Click({
    $form.Close()
})

$form.Controls.Add($button)

$form.ShowDialog()
```

Damit entsteht bereits eine vollständige kleine Windows-Forms-Anwendung:

```text
┌─────────────────────────────────────┐
│ Meine Anwendung                 □ × │
├─────────────────────────────────────┤
│                                     │
│             ┌──────────┐            │
│             │ Schließen│            │
│             └──────────┘            │
│                                     │
└─────────────────────────────────────┘
```

---

## `Size` vs. `ClientSize`

Bei `Form` ist die Unterscheidung besonders wichtig:

```powershell
$form.Size = "800, 600"
```

bestimmt die **gesamte Fenstergröße**.

```powershell
$form.ClientSize = "800, 600"
```

bestimmt dagegen die Größe des **nutzbaren Bereichs innerhalb des Fensterrahmens**.

Das ist einer dieser kleinen .NET-Unterschiede, die zunächst völlig harmlos aussehen und später dafür sorgen, dass ein Layout um exakt die Höhe der Titelleiste danebenliegt.

---

## `Show()` vs. `ShowDialog()`

| Methode        | Modal | Blockiert Code | Rückgabewert   |
| -------------- | ----: | -------------: | -------------- |
| `Show()`       |     ❌ |              ❌ | keiner         |
| `ShowDialog()` |     ✅ |              ✅ | `DialogResult` |

Für ein normales Hauptfenster:

```powershell
$form.Show()
```

Für einen Dialog:

```powershell
$result = $form.ShowDialog()
```

---

# Hinweise

* `Form` ist selbst ein `Control` und kann deshalb viele Eigenschaften und Events der Basisklasse verwenden.
* Ein Formular besitzt eine `Controls`-Collection und kann damit als Container für andere Controls dienen.
* `Show()` eignet sich für nicht-modale Fenster.
* `ShowDialog()` eignet sich für modale Dialogfenster.
* `Close()` schließt das Formular, während `Hide()` es lediglich unsichtbar macht.
* `Dispose()` gibt die verwendeten Ressourcen frei.
* `ClientSize` beschreibt den nutzbaren Inhaltsbereich, `Size` dagegen die gesamte Fenstergröße.
* `StartPosition` ist für die Positionierung beim ersten Anzeigen zuständig.
* `KeyPreview` ist nützlich, wenn das Formular Tastatureingaben unabhängig vom fokussierten Control verarbeiten soll.
* `AcceptButton` und `CancelButton` erleichtern die Umsetzung klassischer Dialogfenster.

Damit ist `Form` im Grunde die oberste Ebene deiner gesamten WinForms-Struktur. `Panel`, `TableLayoutPanel`, `TabControl` und Co. organisieren den Inhalt darin, während `Form` das eigentliche Fenster und dessen Lebenszyklus verwaltet. Das passt auch ziemlich genau zu dem Aufbau, den du in deinen eigenen PowerShell-UI-Strukturen bereits verwendest.