Anordnen von Ansichten mit Grid
Angenommen, Sie erstellen eine Seite, die Bilder in einem 7×5-Raster anzeigt. Es wäre möglich, hierfür mehrere horizontale und vertikale StackLayout
-Container zu verwenden. Die Programmierung wäre aber ausgesprochen mühsam, und es könnte aufgrund der Arbeitsspeicher- und Verarbeitungsanforderungen mehrerer Layoutpanels zu Leistungsproblemen kommen. Das Layoutpanel Grid
ist die bessere Wahl für Benutzeroberflächen, auf denen sowohl Zeilen als auch Spalten benötigt werden. In dieser Einheit erfahren Sie, wie Sie ein Raster (Grid
) definieren und Ansichten in den Zellen positionieren.
Was ist ein Grid-Layout?
Ein Raster (Grid
) ist ein Layoutpanel, das aus Zeilen und Spalten besteht. Die folgende Abbildung zeigt eine konzeptionelle Ansicht eines solchen Rasters.
Sie platzieren View-Elemente in den Zellen, die durch die Überschneidung der Zeilen und Spalten entstehen. Wenn Sie beispielsweise ein Raster (Grid
) mit drei Spalten und zwei Zeilen erstellen, stehen sechs Zellen für Ansichten zur Verfügung. Die Zeilen und Spalten können unterschiedliche Größen aufweisen oder so eingerichtet werden, dass sie sich automatisch an die untergeordneten Elemente anpassen, die in den Zellen platziert werden. Untergeordnete Ansichten können eine Zelle belegen oder sich über mehrere Zellen erstrecken. Aufgrund dieser Flexibilität ist Grid
eine gute Wahl für das Stammlayoutpanel vieler Apps.
Angeben der Zeilen und Spalte eines Grid-Layouts
Wenn Sie ein Grid
erstellen, können Sie jede Zeile und Spalte einzeln definieren. Dieses System bietet Ihnen vollständige Kontrolle über die Höhe jeder Zeile und die Breite jeder Spalte. Jedes Grid
verfügt über eine Sammlung aus RowDefinition
- und ColumnDefinition
-Objekten, die die Form des Rasters definieren. Sie füllen diese Sammlungen mit Instanzen von RowDefinition
und ColumnDefinition
auf, die jeweils eine Zeile bzw. eine Spalte Ihrer Benutzeroberfläche darstellen.
Die folgenden beiden Codeausschnitte zeigen die Klassendefinitionen für RowDefinition
und ColumnDefinition
:
public sealed class RowDefinition : ...
{
...
public GridLength Height { get; set; }
}
public sealed class ColumnDefinition : ...
{
...
public GridLength Width { get; set; }
}
Beachten Sie, dass RowDefinition
eine Eigenschaft namens Height
und ColumnDefinition
eine Eigenschaft namens Width
besitzt. Sie verwenden diese Eigenschaften, um die Höhe einer Zeile und die Breite einer Spalte festzulegen, wie in den folgenden Abschnitten beschrieben.
Was ist GridLength?
Der Datentyp für die Eigenschaften Width
und Height
ist GridLength
. Dieser Typ enthält zwei Eigenschaften: GridUnitType
und Value
. Der folgende Codeausschnitt zeigt einen Teil der Typdefinition.
public struct GridLength
{
...
public GridUnitType GridUnitType { get; }
public double Value { get; }
}
Sie können die Eigenschaft GridUnitType
auf einen der folgenden Werte festlegen:
Absolute
Auto
Star
Sehen wir uns die einzelnen Werte einmal näher an.
GridUnitType: Absolute
Absolute
gibt an, dass die Zeile oder Spalte eine feste Größe haben soll. Die Eigenschaft Value
dient zum Angeben der Größe. Das folgende Beispiel zeigt, wie Sie in C# die Höhe einer Zeile auf die feste Größe von 100
Geräteeinheiten festlegen. Beachten Sie, wie Sie den GridLength
-Konstruktor verwenden, der einen numerischen Wert akzeptiert. Der Konstruktor legt GridUnitType
automatisch auf Absolute
fest.
var row = new RowDefinition() { Height = new GridLength(100) };
In Extensible Application Markup Language (XAML) geben Sie einfach einen numerischen Wert an. Der XAML-Parser ruft einen Typkonverter auf, um die GridLength
-Instanz zu erstellen. Das folgende Beispiel zeigt das Gleiche in XAML:
<RowDefinition Height="100" />
GridUnitType: Auto
Auto
passt die Größe der Zeilen oder Spalten automatisch an die untergeordneten Ansichten an. Das Raster (Grid
) überprüft alle untergeordneten Ansichten in der entsprechenden Zeile oder Spalte, wählt die größte Ansicht aus und macht die Zeile oder Spalte so groß, dass diese untergeordnete Ansicht hineinpasst. Wenn Sie eine Zeilendefinition per Code erstellen, wird der numerische Wert ignoriert. Sie können einen beliebigen Wert verwenden. Das folgende Beispiel zeigt, wie Sie in C# die Höhe einer Zeile so festlegen, dass die Größe automatisch angepasst wird. Beachten Sie, dass wir hier willkürlich 1
als Wert ausgewählt haben.
var row = new RowDefinition() { Height = new GridLength(1, GridUnitType.Auto) };
In XAML verwenden Sie den Wert Auto
. Das folgende Beispiel zeigt das Gleiche in XAML:
<RowDefinition Height="Auto" />
GridUnitType: Star
Star
ermöglicht eine proportionale Größenanpassung. Bei der proportionalen Größenanpassung wird die Größe durch den insgesamt verfügbaren Platz und das Verhältnis bestimmt, das für die einzelnen Zeilen oder Spalten erforderlich ist. Dies wird häufig auch als Größenanpassung mit Sternvariabler anstatt als proportionale Größenanpassung bezeichnet.
Sehen wir uns den Prozess der proportionalen Größenanpassung für die Zeilen in einem Raster einmal an.
Bestimmen Sie den verfügbaren Platz: Das
Grid
überprüft alle Zeilen, dieGrid
die Größenanpassung mit Sternvariable verwenden. Die Höhen all dieser Zeilen werden addiert, und diese Gesamtsumme wird von der Höhe desGrid
-Elements selbst subtrahiert. Diese Berechnung gibt den Platz an, der für alle Zeilen mit Sternvariabler insgesamt verfügbar ist.Teilen Sie den verfügbaren Platz auf: Das
Grid
teilt den verfügbaren Platz auf alle Zeilen mit Sternvariabler auf, basierend auf derValue
-Einstellung für jede Zeile. Stellen Sie sich dieValue
-Eigenschaft als Multiplikator vor, der das Verhältnis zwischen allen Zeilen bestimmt, die als „mit Sternvariabler“ definiert sind. Ein Beispiel: Sie haben zwei Zeilen mit Sternvariabler, die beide1
als Multiplikator aufweisen. Dann wird der verfügbare Platz gleichmäßig auf beide Zeilen aufgeteilt. Wenn jedoch eine der beiden Zeilen2
als Wert aufwiese, würde sie doppelt so viel Platz erhalten wie die andere.
Das folgende Beispiel zeigt, wie Sie in C# die Höhe einer Zeile als 2 Star
festlegen:
var row = new RowDefinition() { Height = new GridLength(2, GridUnitType.Star) };
In XAML verwenden Sie das Symbol *
, um die Größenanpassung mit Sternvariabler darzustellen. Sie kombinieren den Wert und das *
-Symbol in einer einzigen Zeichenfolge, und ein Typkonverter erstellt die GridLength
für Sie. Hier sehen Sie das Beispiel in XAML.
<RowDefinition Height="2*" />
Grid-Sammlungen
Nachdem Sie Zeilen und Spalten mithilfe von RowDefinition
und ColumnDefinition
definiert haben, können Sie sie einem Raster (Grid
) hinzufügen. Sie verwenden die Sammlungseigenschaften RowDefinitions
und ColumnDefinitions
des Grid
. Das Auffüllen dieser Sammlungen erfolgt meistens in XAML.
Dieses Beispiel zeigt, wie Sie vier Zeilen definieren und mithilfe der RowDefinitions
-Eigenschaft zu einem Grid
hinzufügen:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="100" />
<RowDefinition Height="Auto" />
<RowDefinition Height="1*" />
<RowDefinition Height="2*" />
</Grid.RowDefinitions>
...
</Grid>
Diese Definition kann wie folgt gekürzt werden:
<Grid RowDefinitions="100, Auto, 1*, 2*">
...
</Grid>
Der XAML-Code zum Definieren von Spalten entspricht dem vorherigen XAML. Abgesehen davon, dass Sie ColumnDefinitions
verwenden und den Wert für Width
angeben würden.
Zur Laufzeit erzeugt dieser XAML-Code ein Raster (Grid
) mit vier Zeilen. Die erste Zeile hat eine feste Höhe von 100
Geräteeinheiten. Die zweite Zeile hat die Höhe der höchsten Ansicht in der Zeile. Die dritte und vierte Zeile verwenden die Größenanpassung mit Sternvariabler. Das bedeutet, dass der verbleibende verfügbare Platz basierend auf dem Value
-Multiplikator proportional aufgeteilt wird. Da der Multiplikator für die dritte Zeile 1*
und für die vierte Zeile 2*
lautet, ist die vierte Zeile doppelt so hoch wie die dritte.
Standardgröße für Zeilen und Spalten
Der Standardwert für Zeilen und Spalten ist die Größe 1*
. Sehen Sie sich beispielsweise folgende XAML an:
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
...
</Grid>
Diese Definition kann wie folgt gekürzt werden:
<Grid RowDefinitions="*, *, *" ColumnDefinitions="*, *">
...
</Grid>
Da für keine der Zeilen oder Spalten eine Größe angegeben ist, wird 1*
auf alle angewendet. Zur Laufzeit erstellt diese Konfiguration ein gleichförmiges Raster (Grid
), was bedeutet, dass alle Zeilen die gleiche Höhe und alle Spalten die gleiche Breite aufweisen.
Hinzufügen von Ansichten zu einem Grid
Wenn Sie einem Grid
eine Ansicht hinzufügen, fügen Sie sie einer bestimmten Zelle hinzu. Zellen werden an Positionen erstellt, an denen Zeilen und Spalten sich überschneiden. Um eine Ansicht in einer Zelle zu platzieren, müssen Sie die Position der Zelle kennen. Sie verwenden eine Kombination aus einer Zeilennummer und einer Spaltennummer, um eine Zelle zu identifizieren.
Nummerierung von Zeilen und Spalten
Die Nummerierung von Zeilen und Spalten beginnt bei Null. Der Ursprung ist die linke obere Ecke. Die folgende Abbildung zeigt die Nummerierung für ein Grid
-Element mit vier Zeilen und zwei Spalten.
Wenn Sie beispielsweise der rechten unteren Zelle eine Ansicht hinzufügen möchten, wird die Position der Ansicht folgendermaßen angegeben: row 3 column 1
.
Hinzufügen einer Ansicht zu einem Grid mithilfe von angefügten Eigenschaften
Sie benötigen eine Möglichkeit, die Zeilen- und Spaltennummer einer Ansicht anzugeben, wenn Sie diese einem Grid hinzufügen. Eine Lösung wäre, Row
- und Column
-Eigenschaften in der View
-Basisklasse zu definieren, sodass Sie die Position der Ansicht direkt angeben können. Dieses Verfahren würde funktionieren, ist aber nicht der effizienteste Ansatz. Ansichten befinden sich nicht immer in einem Grid
, daher werden diese Eigenschaften möglicherweise nicht benötigt. Eine bessere Vorgehensweise ist die Verwendung von angefügten Eigenschaften.
Eine angefügte Eigenschaft ist eine Eigenschaft, die in einer einzelnen Klasse definiert, aber für Objekte anderer Typ festgelegt wird.
Sie können sich angefügte Eigenschaften als Sammlung aus Schlüssel-Wert-Paaren vorstellen, die Teil einer Ansicht ist. Wenn Sie einem Grid
eine Ansicht hinzufügen, geben Sie die Zeile und Spalte an. Durch Verwendung von angefügten Eigenschaften können Sie ein Schlüssel-Wert-Paar mit dem Schlüssel Grid.Row
und einem Wert, der die Zeilennummer angibt, hinzufügen. Wenn das Raster (Grid
) bereit ist, die Ansicht zu positionieren, überprüft es die Sammlung, um zu ermitteln, ob ein Schlüssel namens Grid.Row
vorhanden ist. Falls ja, verwendet das Raster (Grid
) diesen Wert, um die Ansicht zu positionieren.
Dieses Beispiel zeigt, wie Sie ein Grid
erstellen und mithilfe von angefügten Eigenschaften eine Ansicht hinzufügen:
<Grid RowDefinitions="*, *, *" ColumnDefinitions="*, *">
<BoxView Grid.Row="1" Grid.Column="0" Color="Navy" />
</Grid>
In diesem Beispiel sind Grid.Row=1
und Grid.Column=0
Schlüssel-Wert-Paare, die einer internen Sammlung der BoxView
hinzugefügt werden. Das Raster (Grid
) verwendet diese Werte, um zu ermitteln, wo die Ansicht positioniert werden soll. So sieht das Grid
-Element aus, wenn Sie die Anwendung auf einem Gerät ausführen:
Festlegen einer Ansicht über mehrere Zeilen oder Spalten
Es gibt zwei weitere angefügte Eigenschaften, die Sie kennen sollten: Grid.RowSpan
und Grid.ColumnSpan
. Diese Eigenschaften geben an, wie viele Zeilen oder Spalten die Ansicht einnehmen soll. Sehen Sie sich beispielsweise folgende XAML an:
<Grid RowDefinitions="*, *, *" ColumnDefinitions="*, *">
<BoxView Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2" Color="Navy" />
</Grid>
Beachten Sie, dass in diesem Beispiel ColumnSpan
auf 2
festgelegt wird. Diese Ansicht belegt zwei Spalten ab Column 0
. So sieht das Grid
-Element aus, wenn Sie die Anwendung auf einem Gerät ausführen: