WPF: Layout-Panels
Bisher haben wir immer das Layout-Panel Grid verwendet. Nun wollen wir auch die anderen Layout-Panels kennenlernen. Ein Layout-Panel (kurz Panel) dient zur Anordnung von Steuerelementen. Einem Layout-Panel können direkt ein oder mehrere Steuerelement(e) untergeordnet werden. Eine Liste mit Steuerelementen können wir über die Eigenschaft Children abrufen. Hier können wir auch über die Funktion Add() ein neues Steuerelement hinzufügen und über Remove() entfernen. Alle Layout-Panels gehören der Basisklasse Panel an. Jedes Layout-Panel von WPF hat verschiedene „Eigenschaften“ und erzeugt somit eine andere Ausgabe. Natürlich können durch verschiedene Attribute wie z. B. Margin, Height und Width mit unterschiedlichen Layout-Panels gleiche Anzeigen erzeugt werden.
Beim Grid-Panel können wir mit Hilfe des untergeordneten Grid.RowDefinitions- und Grid.ColumnDefinitions-Elements Definitionen für Zeilen und Spalten erstellen. Somit ist die Hauptaufgabe des Grid-Panels also die tabellarische Darstellung. Den Elementen werden Elemente des Typs RowDefinition und ColumnDefinition untergeordnet. Hier können wir über die Eigenschaften Height und Width die Größe einer Zeile oder Spalte steuern. Wird die Angabe weggelassen, so wird der Wert automatisch durch die restliche Höhe bzw. Breite ermittelt. Steuerelemente die sich innerhalb des Grid Layout-Panels befinden, können über die Eigenschaften Grid.Row und Grid.Column positioniert werden. Dabei handelt es sich um einen nullbasierenden Index. Soll sich ein Steuerelement über mehrere Zeilen oder Spalten erstrecken, so kann uns die Eigenschaft Grid.RowSpan und Grid.ColumnSpan helfen.
Das UniformGrid wird ebenfalls zur tabellarischen Darstellung verwendet. Jedoch besitzt jede Zeile und jede Spalte eine einheitliche Größe. Die Anzahl an Zeilen und Spalten wird über die Eigenschaft Rows und Columns angegeben. Die untergeordneten Steuerelemente werden über die Reihenfolge, in welcher diese notiert werden, positioniert.
StackPanel ist ein Layout-Panel, bei welchem die Anordnung horizontal untereinander oder vertikal nebeneinander erfolgt. Diese Richtung kann mit Hilfe der Eigenschaft Orientation festgelegt werden: Horizontal (Ausrichtung untereinander von oben nach unten), Vertical (Ausrichtung nebeneinander von links nach rechts).
Beim WrapPanel wird eine Anordnung ähnlich zum StackPanel vorgenommen. Auch hier können wir die Anordnungs-Richtung mit der Eigenschaft Orientation festlegen. Beim WrapPanel werden die Elemente jedoch nicht nur untereinander oder nebeneinander platziert. Vielmehr erfolgt sowohl eine Anordnung untereinander und nebeneinander. Erläutern wir dies etwas genauer für den Horizontal-Wert der Eigenschaft Orientation (Enumeration Orientation): Zuerst werden alle Steuerelemente nebeneinander platziert. Ist der gegebene Platz voll, so wird ein Zeilenumbruch (englisch wordwrap) erzeugt. Dieses Vorgehen kann sich ein bis mehrere Mal(e) wiederholen.
Das Layout-Panel DockPanel erlaubt eine Anordnung an eine der vier Seiten eines Rechtecks (links, oben, rechts oder unten). Hierfür werden die Steuerelemente, welche untergeordnet sind, über die Eigenschaft DockPanel.Dock angeordnet. Mögliche Werte sind Left, Top, Right und Bottom. Natürlich können die Anordnungen an eine bestimmte Seite auch gestapelt werden (siehe Beispiel). Die Eigenschaft LastChildFill bestimmt, ob das letzte untergeordnete Element den restlichen Platz des Layout-Panels auffüllen soll. Der Standardwert der Eigenschaft ist true. Steuerelemente bei denen das DockPanel.Dock-Attribut nicht gesetzt ist, werden automatisch links angeordnet.
Das letzte Layout-Panel, welches wir uns anschauen möchten, ist Canvas. Das Canvas-Panel eignet sich sehr gut für die absolute Anordnung von Steuerelementen. Hierbei können die untergeordneten Steuerelemente über Canvas.Left, Canvas.Top, Canvas.Right und Canvas.Bottom angeordnet werden. Natürlich können wir auch Steuerelemente gegeneinander überlagern. Hierbei kann es notwendig sein, die Reihenfolge auf der Z-Achse zu ändern. Die Eigenschaft Canvas.ZIndex legt den Index für die Anordnung auf der Z-Achse fest. Dabei gilt, umso größer der Wert, umso weiter „vorne“ befindet sich das Steuerelement.
MainWindow.xaml
<Grid> <Grid.RowDefinitions> <RowDefinition Height="100" /> <RowDefinition Height="100" /> <RowDefinition Height="100" /> <RowDefinition /> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="250" /> <ColumnDefinition /> </Grid.ColumnDefinitions> <StackPanel Grid.Row="0" Grid.Column="0" Orientation="Vertical"> <Button Content="Button 1" /> <Button Content="Button 2" /> <Button Content="Button 3" /> <Button Content="Button 4" /> </StackPanel> <StackPanel Grid.Row="0" Grid.Column="1" Orientation="Horizontal"> <Button Content="Button 1" /> <Button Content="Button 2" /> <Button Content="Button 3" /> <Button Content="Button 4" /> </StackPanel> <WrapPanel Grid.Row="1" Grid.Column="0"> <Button Content="Button 1" /> <Button Content="Button 2" /> <Button Content="Button 3" /> <Button Content="Button 4" /> <Button Content="Button 5" /> <Button Content="Button 6" /> <Button Content="Button 7" /> </WrapPanel> <DockPanel Grid.Row="1" Grid.Column="1"> <Button Content="Button 1" DockPanel.Dock="Left" /> <Button Content="Button 2" DockPanel.Dock="Left" /> <Button Content="Button 3" DockPanel.Dock="Top" /> <Button Content="Button 4" DockPanel.Dock="Right" /> <Button Content="Button 5" DockPanel.Dock="Bottom" /> <Button Content="Button 6" /> </DockPanel> <Canvas Grid.Row="2" Grid.Column="0"> <Button Canvas.Left="25" Canvas.Top="25" Content="Button 1" /> <Button Canvas.Left="185" Canvas.Top="25" Content="Button 2" /> <Button Canvas.Left="115" Canvas.Top="50" Content="Button 3" /> <Button Canvas.Left="5" Canvas.Bottom="5" Content="Button 4" /> <Button Canvas.Right="25" Canvas.Bottom="5" Content="Button 5" /> </Canvas> <UniformGrid Grid.Row="3" Grid.Column="0" Grid.ColumnSpan="2" Rows="3" Columns="3"> <Button Content="Button 1" /> <Button Content="Button 2" /> <Button Content="Button 3" /> <Button Content="Button 4" /> <Button Content="Button 5" /> <Button Content="Button 6" /> <Button Content="Button 7" /> <Button Content="Button 8" /> <Button Content="Button 9" /> </UniformGrid> </Grid>