## 19.5 Einfache Eingabesteuerelemente ### 19.5.1 Das Steuerelement »Label« Ein Label dient in einem Window dazu, Text anzuzeigen. Es gehört zu den sogenannten Content-Steuerelementen, hat also eine Eigenschaft Content. Die Größe eines Labels ergibt sich aus dem Inhalt. Sie sollten daher die Größe nicht ausdrücklich angeben, da der anzuzeigende Text ansonsten unter Umständen abgeschnitten wird. Eine Besonderheit dieses Steuerelements ist die mögliche Definition eines Hotkeys. Wird die -Taste zusammen mit dem Hotkey gedrückt, erhält ein anderes Steuerelement den Tastaturfokus. Das Tastenkürzel wird im Text des Label-Steuerelements durch einen Unterstrich ausgedrückt. Die Zuordnung des Steuerelements, das den Tastaturfokus erhalten soll, erfolgt mit der Target-Eigenschaft. So könnten Sie beispielsweise festlegen, dass beim Drücken von + die TextBox mit dem Bezeichner txtWohnort den Fokus erhält. Das entsprechende Codefragment dazu sieht wie folgt aus:
    <Label Target="{Binding ElementName=txtWohnort}"
           Height="28" Name="label1" Width="80">_Wohnort:</Label>
    <TextBox Height="25" Name="txtWohnort" Width="120" />
Zur Laufzeit wird der Access-Key allerdings erst dann sichtbar, wenn die Taste gedrückt wird. Wollen Sie innerhalb der Zeichenfolge einen Unterstrich schreiben, müssen Sie zwei angeben. Ein Label unterstützt von Haus aus keine Zeilenumbrüche. Aber es gibt zwei Möglichkeiten, dennoch Zeilenumbrüche zu erzwingen: TextBlock AccessText TextBlock ist ein Steuerelement, das wir später noch behandeln werden. Das Zusammenspiel zwischen der Content-Eigenschaft des Labels mit einem TextBlock-Objekt gestattet es, Zeilenumbrüche darzustellen.
    <Label>
      <TextBlock TextWrapping="Wrap">
        Hier wird ein Zeilenumbruch gezeigt.
      </TextBlock>
    </Label>
Nachteilig ist der Einsatz eines TextBlock-Elements, wenn Sie einen Hotkey bereitstellen wollen. Der TextBlock wird den Unterstrich auch als solchen darstellen. Für eine Kombination aus Zeilenumbruch und Hotkey eignet sich das AccessText-Element.
    <Label Target="{Binding TextBox1}">
      <AccessText TextWrapping="Wrap">
         Hier wird ein _Zeilenumbruch mit Hotkey gezeigt.
      </AccessText>
    </Label>
### 19.5.2 Das Steuerelement »TextBox« Die TextBox dient dazu, die Texteingabe eines Benutzers entgegenzunehmen oder einfach nur Text anzuzeigen. Dabei kann es sich um ein- oder mehrzeiligen unformatierten Text handeln. Von Haus aus ist die TextBox bereits mit vielen Fähigkeiten ausgestattet. Beispielsweise beherrscht sie den Datenaustausch über die Zwischenablage, hat eine eingebaute Rechtschreibkorrektur und darüber hinaus auch noch eine mehrstufige Undo-Funktion. Alle angeführten Verhaltensweisen können genutzt werden, ohne dass Sie eine Zeile Code schreiben müssen. #### Größe des Steuerelements Die Größe einer TextBox ergibt sich aus ihrem Inhalt. Je nachdem, in welchem Panel die TextBox platziert ist, kann ihre Größe auf unvertretbares Maß schrumpfen. Es ist daher empfehlenswert, eine TextBox in einem Panel unterzubringen, das zumindest die Breite des Inhalts vorgibt. Das wäre beispielsweise in einem StackPanel oder einer Grid-Zelle mit der Einstellung Width=*. Sie können zwar auch die Eigenschaft MinWidth einstellen, aber damit geht unter anderem auch die Anpassungsfähigkeit an andere Schriftgrößen verloren. Berücksichtigen sollten Sie auch die Höhe einer TextBox, die mehrere Zeilen anzeigen kann. Anstatt MinHeight und MaxHeight festzulegen, sollten Sie besser die Eigenschaften MinLines und MaxLines verwenden. Diese beiden Eigenschaften limitieren die Zeilen und berücksichtigen dabei die aktuelle Schriftart und -größe. #### Texteingabe Per Vorgabe ist die Eingabe in einer TextBox immer einzeilig. Mit der Einstellung AcceptsReturn=True geben Sie an, dass beim Drücken der Eingabetaste eine neue Zeile eingefügt werden kann. Der Benutzer kann dann auch mehrzeilige Texte eingeben. Behalten Sie die Vorgabe AcceptsReturn=False bei, wird beim Drücken der Eingabetaste der Standard-Button betätigt. Ähnliches gilt für die Eigenschaft AcceptsTab. Stellen Sie die Eigenschaft auf True ein, wird ein Tabulator in die TextBox eingefügt. Mit False wird zum nächsten Steuerelement in der Aktivierungsreihenfolge geschaltet. Bei umfangreichen Texten sollten Sie berücksichtigen, Schiebebalken zu aktivieren. Das geschieht mit den Eigenschaften VerticalScrollBarVisibility und HorizontalScrollBarVisibility, die Sie auf Auto stellen sollten. Beide Eigenschaften sind vom Typ der Enumeration ScrollBarVisibility, deren Werte Sie Tabelle 19.6 entnehmen können.

Tabelle 19.6 Werte der Enumeration »ScrollBarVisibility«

Einstellung | Beschreibung
Auto | Falls notwendig, wird ein Rollbalken automatisch angezeigt.
Disabled | Der Rollbalken wird nur im Bedarfsfall angezeigt.
Hidden | Ein Rollbalken wird auch dann nicht angezeigt, wenn es erforderlich wäre.
Visible | Der Rollbalken wird immer angezeigt.
Überschreitet die Benutzereingabe die Breite der TextBox, wird über den rechten Rand hinaus geschrieben. Sie können mit der Eigenschaft TextWrapping=Wrap erzwingen, dass die Eingabezeile umbrochen wird, sobald das Ende der TextBox erreicht ist (die Standardvorgabe ist TextWrapping=NoWrap). Dabei sollten Sie aber Vorsicht walten lassen. Handelt es sich dabei um ein sehr langes Wort, wird es mittendrin umbrochen. Könnte ein solcher Fall auftreten, sollten Sie sich besser für die dritte Einstellmöglichkeit, WrapWithOverFlow, entscheiden. Diese umbricht das Wort zwar nicht mittendrin, hat aber zur Folge, dass die Zeile länger wird, als von der angegebenen Größe der TextBox vorgesehen ist. #### Textanzeige Der Inhalt der TextBox wird durch die Eigenschaft Text beschrieben. Sie können diese Eigenschaft auch mit Code festlegen oder auswerten. Die Ausrichtung des Textes erfolgt mit der Eigenschaft TextAlignment. Zulässige Werte sind vom Typ der Enumeration TextAlignment. Sie sind Tabelle 19.7 zu entnehmen.

Tabelle 19.7 Textausrichtung mit der Enumeration »TextAlignment«

Wert | Beschreibung
Center | Der Text wird in der TextBox zentriert ausgerichtet.
Left | Der Text wird in der TextBox links ausgerichtet.
Right | Der Text wird in der TextBox rechts ausgerichtet.
Justify | Der Text wird in der TextBox so ausgerichtet, dass alle Zeilen die gleiche Länge haben.
Mit der Eigenschaft TextDecoration lässt sich der Text »verzieren«. Genauer gesagt, können Sie die Dekorationen Overline, Underline, Baseline und Strikethrough einstellen.
    <TextBox FontSize="36">
      <TextBox.TextDecorations>
        <TextDecoration Location="Underline"/>
      </TextBox.TextDecorations>
      Testtext
    </TextBox>
Dekorationen können in vielerlei Hinsicht gestylt werden. So können Sie gestrichelte Dekorationen, aber auch Dekorationen mit Farbverlauf realisieren.
Hinweis
Fette oder kursive Schrift wird nicht über TextDecorations eingestellt, sondern über die Eigenschaft der eingestellten Schriftart.
#### Markierter Text Den vom Anwender markierten Text liefert die Eigenschaft SelectedText. Die Länge des selektierten Textes kann mit SelectionLength abgefragt werden. Die dritte Eigenschaft, SelectionStart, gibt an, bei welchem Buchstaben die Auswahl beginnt. Dabei wird von Textbeginn an gezählt, wobei der erste Buchstabe in der TextBox den Wert 0 hat. Ist in dem Text »Aachen« beispielsweise die Teilzeichenfolge »chen« selektiert, liefert SelectionStart den Wert 2. #### Methoden zur Bearbeitung von Text Zum Kopieren, Ausschneiden und Einfügen stehen die Methoden Copy, Cut und Paste zur Verfügung. Mit der Methode SelectAll wird der komplette Inhalt der TextBox markiert. Undo macht die letzte Aktion rückgängig, und Redo macht den letzten Rückgängig-Befehl rückgängig. Die Anzahl der Undo- und Redo-Aktionen ist theoretisch unbegrenzt, das heißt, die Grenzen werden nur durch den zur Verfügung stehenden Speicher gesetzt. So ist zumindest die Voreinstellung. Ein sinnvoller Grenzwert kann mit der Eigenschaft UndoLimit festgelegt werden. Möchten Sie die Undo- und Redo-Aktionen generell ausschalten, stellen Sie die Eigenschaften CanUndo und CanRedo auf false ein. Interessant ist in diesem Zusammenhang auch, mehrere Bearbeitungsschritte mit den Methoden BeginChange und EndChange zusammenzufassen. Diese Aktionen werden dann als ein einziger Undo-Schritt gewertet. Allerdings geht das natürlich nur im Programmcode. #### Rechtschreibprüfung Wie bereits am Anfang erwähnt wurde, unterstützt die WPF-TextBox auch die Rechtschreibprüfung. Dieses Verhalten muss allerdings erst mit SpellCheck.IsEnabled = true aktiviert werden. Es kommt dann automatisch die in den Systemeinstellungen ausgewählte Sprache zur Anwendung. Wünschen Sie eine andere Sprache, geben Sie diese der Eigenschaft Language als Sprachcode an (z. B. Language = en-us). Sie können sogar zwischen der alten und der neuen Rechtschreibung auswählen. Auch dafür dient die Eigenschaft SpellCheck, die neben IsEnabled auch noch SpellingReform anbietet. Hier klicken, um das Bild zu vergrößern Abbildung 19.9 Rechtschreibprüfung einer »TextBox« Einen Haken hat die Rechtschreibprüfung aber immer noch. Auch in der aktuellen Version des .NET Framewoks sucht man immer noch vergeblich nach einer ausreichenden Dokumentation. Sie war und ist weiterhin verbesserungswürdig. Zudem gibt es auch keine Möglichkeit, die Rechtschreibkontrolle durch eigene Wörterbücher zu verbessern. ### 19.5.3 Das Steuerelement »PasswordBox« Das Steuerelement PasswordBox dient zur Eingabe eines Passworts. Dieses Control ist deutlich einfacher in der Handhabung als eine TextBox, da viele Eigenschaften und Methoden einer TextBox nicht angeboten werden. Das vom Benutzer eingegebene Passwort wird nicht als Text angezeigt, da die einzelnen Buchstaben durch ein Maskierungszeichen ersetzt werden. Per Vorgabe handelt es sich dabei um einen fetten Punkt. Sie können mit der Eigenschaft PasswordChar aber auch ein anderes Zeichen festlegen. Die eingegebene Zeichenfolge kann über die Eigenschaft Password ausgewertet werden. Erwähnenswert ist ein Ereignis dieses Steuerelements: PasswordChanged. Das Ereignis tritt auf, wenn sich die Eigenschaft Password ändert. Damit wäre es Ihnen möglich, die Anzahl der Fehlversuche zu protokollieren und gegebenenfalls weitere Eingabeversuche zu unterbinden. ### 19.5.4 Das Steuerelement »TextBlock« Das TextBox-Steuerelement ist nur zur Anzeige unformatierter Texte geeignet. Stilistische Änderungen innerhalb des angezeigten Textes sind nicht möglich. Eine TextBlock-Komponente ist in dieser Hinsicht etwas attraktiver. Allerdings kann der Inhalt nicht verändert werden. Sehen wir uns an, welche Möglichkeiten in einem TextBlock stecken. Dabei soll nur ein kleiner Auszug aus den zur Verfügung stehenden Möglichkeiten gezeigt werden. #### Silbentrennung Mit der Eigenschaft IsHyphenationEnabled = true legen Sie fest, dass die automatische Silbentrennung von Wörtern aktiviert ist. Anzumerken ist dabei, dass die Silbentrennung nicht immer einwandfrei funktioniert, obwohl laut Dokumentation die Standardregeln der Grammatik zugrunde liegen. #### Zeilenumbruch (manuell) Mit dem Element <LineBreak /> können Sie einen manuellen Zeilenumbruch in den angezeigten Text einfügen. #### Zeilenumbruch (automatisch) Geben Sie in einem TextBlock einen sehr langen Text ein, wird dieser standardmäßig am Ende abgeschnitten. Die Einstellung TextWrapping = Wrap bewirkt einen automatischen Zeilenumbruch, allerdings auch mitten im Wort. Mit TextWrapping = WrapWithOverflow wird ein Umbruch möglich, aber nicht mitten im Wort. Mit der Einstellung NoWrap wird kein Zeilenumbruch ausgeführt. #### Textbeschneidungen Wird ein Text innerhalb einer dargestellten Zeile zu lang, wird er normalerweise abgeschnitten oder umbrochen. Eine dritte Variante besteht darin, Fortsetzungszeichen in Form von drei Punkten anzuzeigen. Für dieses Verhalten ist die Eigenschaft TextTrimming verantwortlich. TextTrimming kennt drei Werte, die Sie Tabelle 19.8 entnehmen können.

Tabelle 19.8 Die Werte der »TextTrimming«- Enumeration

Wert | Beschreibung
None | Der Text wird nicht abgeschnitten.
CharacterEllipsis | Der Text wird an einer Zeichengrenze abgeschnitten, und drei Punkte werden als Auslassungszeichen dargestellt.
WordEllipsis | Der Text wird an einer Wortgrenze abgeschnitten, und drei Punkte werden als Auslassungszeichen dargestellt.
    <TextBlock TextWrapping="Wrap" TextTrimming="CharacterEllipsis">
      DasIstWortEins DasIstWortzwei DasIstWortDrei
    </TextBlock>
    <TextBlock TextWrapping="NoWrap" TextTrimming="CharacterEllipsis">
      DasIstWortEins DasIstWortzwei DasIstWortDrei
    </TextBlock>
    <TextBlock TextWrapping="NoWrap" TextTrimming="WordEllipsis">
      DasIstWortEins DasIstWortzwei DasIstWortDrei
    </TextBlock>
    <TextBlock TextWrapping="WrapWithOverflow" TextTrimming="CharacterEllipsis">
      DasIstWortEins DasIstWortzwei DasIstWortDrei
    </TextBlock>
Hier klicken, um das Bild zu vergrößern Abbildung 19.10 Einstellungen der Eigenschaften »TextWrapping« und »TextTrimming« #### Allgemeine Textdarstellung Mit den Elementen <Bold> und <Italic> lassen sich einzelne Wörter fett oder kursiv anzeigen. Tatsächlich können Sie auch mit dem von HTML bekannten <Span>-Element besondere Textdarstellungen erreichen, beispielsweise um den vom <Span>-Element eingegrenzten Textbereich farblich anders zu gestalten oder eine andere Schriftart zu verwenden. Im folgenden Beispielcode werden einige der zuvor aufgeführten Elemente innerhalb eines TextBlock-Elements gezeigt.
    <Grid>
      <Border Padding="10">
        <TextBlock FontSize="18" TextWrapping="Wrap"
                                 IsHyphenationEnabled="True">
          Das ist ein <Italic>sehr</Italic> langer <Bold>Text</Bold>
          in einem TextBlock-Element.
          <LineBreak /><LineBreak />
          Bitte schauen Sie sich an, wie einzelne Textabschnitte innerhalb
          dies Textes unterschiedlich formiert werden können.
          <LineBreak />
          Naürlich kann auch die <Span FontFamily="Courier New">
          Schriftart</Span>, die <Span Foreground="Red" FontWeight="Bold">
          Schriftfarbe</Span> oder der <Span Background="Red">Hintergrund</Span>
          angepasst werden.
        </TextBlock>
      </Border>
    </Grid>
Hier klicken, um das Bild zu vergrößern Abbildung 19.11 Textformatierungen im »TextBlock« #### Texteffekte Unter Zuhilfenahme von Transformationen können Sie die gesamte TextBlock-Komponente manipulieren. Mit der Eigenschaft TextEffects geht das sogar mit einzelnen Buchstaben. TextEffects verwaltet dazu eine Collection von TextEffect-Objekten. Jedes TextEffect-Objekt wird durch eine Reihe von Eigenschaften beschrieben, wobei die wichtigsten PositionStart, PositionCount und Transform sind. PositionStart legt dabei den Buchstaben fest, ab dem der Effekt beginnen soll, PositionCount die Anzahl der Buchstaben. Transform schließlich beschreibt den Effekt. Das folgende Beispiel soll Ihnen zumindest ansatzweise zeigen, welche Möglichkeiten sich hinter TextEffects verbergen. Hier werden jeweils die Anfangsbuchstaben zweier Wörter gekippt:
    <StackPanel>
      <TextBlock FontSize="30">
        Hallo Aachen
        <TextBlock.TextEffects>
          <TextEffect PositionStart="0" PositionCount="1">
            <TextEffect.Transform>
              <RotateTransform Angle="-45" CenterX="10" CenterY="15" />
            </TextEffect.Transform>
          </TextEffect>
          <TextEffect PositionStart="6" PositionCount="1">
            <TextEffect.Transform>
              <RotateTransform Angle="40" CenterX="90" CenterY="25" />
            </TextEffect.Transform>
          </TextEffect>
        </TextBlock.TextEffects>
      </TextBlock>
    </StackPanel>
Hier klicken, um das Bild zu vergrößern Abbildung 19.12 Texteffekte ### 19.5.5 Das Steuerelement »Tooltip« In Windows-Anwendungen werden Zusatzinformationen über kleine Rechtecke bereitgestellt, die als Tooltipps bezeichnet werden. Angezeigt werden Tooltipps immer dann, wenn die Maus sich über einem Steuerelement oder einer Komponente befindet und eine Weile nicht bewegt wird. Jeder Komponente kann ein eigener Tooltipp zugeordnet werden. Dazu dient die Eigenschaft ToolTip der Komponenten. Im einfachsten Fall kann ein ToolTip-Element wie im folgenden Listing gezeigt festgelegt werden:
    <StackPanel>
      <Button Height="40" Width="150">
        Beenden
        <Button.ToolTip>
          Hiermit schließen Sie das Fenster
        </Button.ToolTip>
      </Button>
    </StackPanel>
Sie können aber die Fähigkeiten der WPF nutzen und den Inhalt der ToolTip-Eigenschaft frei definieren. Im folgenden Listing wird dazu ein StackPanel verwendet, das seinerseits ein Label- und ein TextBlock-Element enthält.
    <StackPanel>
      <Button Height="40" Width="150">
        Beenden
        <Button.ToolTip>
          <StackPanel>
            <Label FontSize="14" HorizontalAlignment="Center" Foreground="Red"
                   FontWeight="Bold">Achtung!</Label>
            <TextBlock MaxWidth="250" TextWrapping="Wrap">Durch Klicken dieser
                       Schaltfläche wird das Fenster geschlossen und alle
                       Änderungen gehen verloren.
            </TextBlock>
          </StackPanel>
        </Button.ToolTip>
      </Button>
    </StackPanel>
Hier klicken, um das Bild zu vergrößern Abbildung 19.13 Ein ToolTip-Steuerelement Sie können die Anzeige des ToolTips nach eigenem Ermessen konfigurieren. Dazu verwenden Sie die Klasse ToolTipService. Mit deren Hilfe können Sie beispielsweise mit der Eigenschaft ShowDuration die Anzeigedauer bestimmen und mit InitialShowDelay die Verzögerung festlegen, bis ein Tooltipp angezeigt wird. Die Zeitangaben erfolgen in Millisekunden. Standardmäßig erfolgt die Anzeige des ToolTips beim Mauszeiger, sie kann aber mit den Eigenschaften HorizontalOffset, VerticalOffset, PlacementTarget und PlacementRectangle auch nach eigenen Vorstellungen eingestellt werden. Auch diese Eigenschaften stellen Sie mit ToolTipService direkt im betreffenden Element ein.
    <Button Height="40" Width="150"
             ToolTipService.ShowDuration="3000"
             ToolTipService.InitialShowDelay="500">
      Beenden
      ...
    </Button>