Layout-Panels
Panels ordnen ihre Kinder an: StackPanel reiht sie auf, WrapPanel bricht in die nächste Zeile um, DockPanel legt sie an die Ränder und füllt mit dem letzten, Grid teilt in Zeilen und Spalten (Pixel, Auto, Stern), Canvas setzt sie an feste Koordinaten.


KXAML
LayoutSeite.kxaml
<StackPanel xmlns="https://ui.kuonen.org/kxaml"
xmlns:x="https://ui.kuonen.org/kxaml/x"
x:Class="Kuonen.UI.Galerie.Seiten.LayoutVorfuehrung"
Spacing="8">
<!-- Jedes Feld: Border mit runden Ecken und reihum einer von fünf Farben, darin ein Text. -->
<TextBlock Text="StackPanel" FontWeight="SemiBold" Margin="0,8,0,0" />
<!-- StackPanel: waagrecht mit Abstand. -->
<StackPanel Orientation="Horizontal" Spacing="8">
<Border Width="Auto" Height="32" CornerRadius="4" Background="#CCE4F7">
<TextBlock Text="Kind 1" Foreground="#1B1B1B" Margin="8,0,8,0" VerticalAlignment="Center" />
</Border>
<Border Width="Auto" Height="32" CornerRadius="4" Background="#FDE7C5">
<TextBlock Text="Kind 2" Foreground="#1B1B1B" Margin="8,0,8,0" VerticalAlignment="Center" />
</Border>
<Border Width="Auto" Height="32" CornerRadius="4" Background="#D3F0D4">
<TextBlock Text="Kind 3" Foreground="#1B1B1B" Margin="8,0,8,0" VerticalAlignment="Center" />
</Border>
<Border Width="Auto" Height="32" CornerRadius="4" Background="#F5D0E0">
<TextBlock Text="Kind 4" Foreground="#1B1B1B" Margin="8,0,8,0" VerticalAlignment="Center" />
</Border>
</StackPanel>
<TextBlock Text="WrapPanel" FontWeight="SemiBold" Margin="0,8,0,0" />
<!-- WrapPanel: die Schaltfläche fügt Kinder hinzu (im Code-Behind), bis umgebrochen wird. -->
<WrapPanel x:Name="Umbruch" Width="420" HorizontalAlignment="Left">
<Border Width="90" Height="32" CornerRadius="4" Background="#E2D9F3" Margin="0,0,8,8">
<TextBlock Text="Nr. 1" Foreground="#1B1B1B" Margin="8,0,8,0" VerticalAlignment="Center" />
</Border>
<Border Width="90" Height="32" CornerRadius="4" Background="#CCE4F7" Margin="0,0,8,8">
<TextBlock Text="Nr. 2" Foreground="#1B1B1B" Margin="8,0,8,0" VerticalAlignment="Center" />
</Border>
<Border Width="90" Height="32" CornerRadius="4" Background="#FDE7C5" Margin="0,0,8,8">
<TextBlock Text="Nr. 3" Foreground="#1B1B1B" Margin="8,0,8,0" VerticalAlignment="Center" />
</Border>
<Border Width="90" Height="32" CornerRadius="4" Background="#D3F0D4" Margin="0,0,8,8">
<TextBlock Text="Nr. 4" Foreground="#1B1B1B" Margin="8,0,8,0" VerticalAlignment="Center" />
</Border>
<Border Width="90" Height="32" CornerRadius="4" Background="#F5D0E0" Margin="0,0,8,8">
<TextBlock Text="Nr. 5" Foreground="#1B1B1B" Margin="8,0,8,0" VerticalAlignment="Center" />
</Border>
</WrapPanel>
<Button Content="Kind hinzufügen" Click="Hinzu_Click" />
<TextBlock Text="DockPanel" FontWeight="SemiBold" Margin="0,8,0,0" />
<!-- DockPanel: oben, links, unten, das letzte Kind füllt den Rest. -->
<DockPanel Width="420" Height="160" HorizontalAlignment="Left">
<Border Width="Auto" Height="32" CornerRadius="4" Background="#E2D9F3" DockPanel.Dock="Top">
<TextBlock Text="Oben" Foreground="#1B1B1B" Margin="8,0,8,0" VerticalAlignment="Center" />
</Border>
<Border Width="80" Height="Auto" CornerRadius="4" Background="#CCE4F7" DockPanel.Dock="Left">
<TextBlock Text="Links" Foreground="#1B1B1B" Margin="8,0,8,0" VerticalAlignment="Center" />
</Border>
<Border Width="Auto" Height="32" CornerRadius="4" Background="#FDE7C5" DockPanel.Dock="Bottom">
<TextBlock Text="Unten" Foreground="#1B1B1B" Margin="8,0,8,0" VerticalAlignment="Center" />
</Border>
<Border Width="Auto" Height="Auto" CornerRadius="4" Background="#D3F0D4">
<TextBlock Text="Rest (füllt)" Foreground="#1B1B1B" Margin="8,0,8,0" VerticalAlignment="Center" />
</Border>
</DockPanel>
<TextBlock Text="Grid" FontWeight="SemiBold" Margin="0,8,0,0" />
<!-- Grid: Spalten Auto | 1* | 2*, Zeilen Pixel und Stern, ein Kind über zwei Spalten. -->
<Grid Width="420" Height="120" HorizontalAlignment="Left">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="2*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="40" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Border Width="Auto" Height="Auto" CornerRadius="4" Background="#F5D0E0" Margin="2" Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="1">
<TextBlock Text="Auto" Foreground="#1B1B1B" Margin="8,0,8,0" VerticalAlignment="Center" />
</Border>
<Border Width="Auto" Height="Auto" CornerRadius="4" Background="#E2D9F3" Margin="2" Grid.Row="0" Grid.Column="1" Grid.ColumnSpan="1">
<TextBlock Text="1*" Foreground="#1B1B1B" Margin="8,0,8,0" VerticalAlignment="Center" />
</Border>
<Border Width="Auto" Height="Auto" CornerRadius="4" Background="#CCE4F7" Margin="2" Grid.Row="0" Grid.Column="2" Grid.ColumnSpan="1">
<TextBlock Text="2*" Foreground="#1B1B1B" Margin="8,0,8,0" VerticalAlignment="Center" />
</Border>
<Border Width="Auto" Height="Auto" CornerRadius="4" Background="#FDE7C5" Margin="2" Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="1">
<TextBlock Text="Zeile 2" Foreground="#1B1B1B" Margin="8,0,8,0" VerticalAlignment="Center" />
</Border>
<Border Width="Auto" Height="Auto" CornerRadius="4" Background="#D3F0D4" Margin="2" Grid.Row="1" Grid.Column="1" Grid.ColumnSpan="2">
<TextBlock Text="über zwei Spalten" Foreground="#1B1B1B" Margin="8,0,8,0" VerticalAlignment="Center" />
</Border>
</Grid>
<TextBlock Text="Canvas" FontWeight="SemiBold" Margin="0,8,0,0" />
<!-- Canvas: feste Koordinaten, auch von rechts unten. -->
<Canvas Width="420" Height="100" HorizontalAlignment="Left" Background="#20808080">
<Border Width="Auto" Height="32" CornerRadius="4" Background="#F5D0E0" Canvas.Left="10" Canvas.Top="10">
<TextBlock Text="Left 10, Top 10" Foreground="#1B1B1B" Margin="8,0,8,0" VerticalAlignment="Center" />
</Border>
<Border Width="Auto" Height="32" CornerRadius="4" Background="#E2D9F3" Canvas.Right="10" Canvas.Bottom="10">
<TextBlock Text="Right 10, Bottom 10" Foreground="#1B1B1B" Margin="8,0,8,0" VerticalAlignment="Center" />
</Border>
</Canvas>
</StackPanel>LayoutSeite.kxaml.cs
using Kuonen.UI;
using Kuonen.UI.Controls;
using Kuonen.UI.Ereignisse;
using Kuonen.UI.Media;
namespace Kuonen.UI.Galerie.Seiten;
public sealed partial class LayoutSeite
{
protected override Func<UIElement>? KxamlFabrik => () => new LayoutVorfuehrung();
}
/// <summary>
/// KXAML-Fassung der Layout-Seite: der Baum steht in LayoutSeite.kxaml (jedes Feld ausgeschrieben – KXAML kennt keine
/// Schleifen), hier fügt die Schaltfläche weitere Felder an.
/// </summary>
public sealed partial class LayoutVorfuehrung
{
private static readonly Color[] Farben =
[
Color.FromRgb(0xCC, 0xE4, 0xF7), Color.FromRgb(0xFD, 0xE7, 0xC5), Color.FromRgb(0xD3, 0xF0, 0xD4),
Color.FromRgb(0xF5, 0xD0, 0xE0), Color.FromRgb(0xE2, 0xD9, 0xF3),
];
private int _naechste = 20; // 20 Felder stehen im KXAML
private int _anzahl = 5; // davon 5 im WrapPanel
public LayoutVorfuehrung() => InitializeComponent();
private void Hinzu_Click(object sender, RoutedEventArgs e)
{
Umbruch.Children.Add(new Border
{
Width = 90, Height = 32, CornerRadius = new CornerRadius(4), Margin = new Thickness(0, 0, 8, 8),
Background = new SolidColorBrush(Farben[_naechste++ % Farben.Length]),
Child = new TextBlock { Text = $"Nr. {++_anzahl}", Foreground = new SolidColorBrush(Color.FromRgb(0x1B, 0x1B, 0x1B)), Margin = new Thickness(8, 0, 8, 0), VerticalAlignment = VerticalAlignment.Center },
});
}
}C#
LayoutSeite.cs
using Kuonen.UI;
using Kuonen.UI.Controls;
using Kuonen.UI.Layout;
using Kuonen.UI.Media;
namespace Kuonen.UI.Galerie.Seiten;
/// <summary>Galerie-Seite: die Layout-Panels StackPanel, WrapPanel, DockPanel, Grid und Canvas.</summary>
public sealed partial class LayoutSeite : GalerieSeite
{
public override string Titel => "Layout-Panels";
public override string Beschreibung =>
"Panels ordnen ihre Kinder an: StackPanel reiht sie auf, WrapPanel bricht in die nächste Zeile um, DockPanel "
+ "legt sie an die Ränder und füllt mit dem letzten, Grid teilt in Zeilen und Spalten (Pixel, Auto, Stern), "
+ "Canvas setzt sie an feste Koordinaten.";
public override string Stichworte => "StackPanel WrapPanel DockPanel Grid Canvas Anordnung Zeilen Spalten Stern Auto Spacing";
public override string Datei => nameof(LayoutSeite);
public override UIElement Baue()
{
var farben = new[]
{
Color.FromRgb(0xCC, 0xE4, 0xF7), Color.FromRgb(0xFD, 0xE7, 0xC5), Color.FromRgb(0xD3, 0xF0, 0xD4),
Color.FromRgb(0xF5, 0xD0, 0xE0), Color.FromRgb(0xE2, 0xD9, 0xF3),
};
int naechste = 0;
Border Feld(string text, double breite = double.NaN, double hoehe = 32) => new()
{
Width = breite, Height = hoehe, CornerRadius = new CornerRadius(4),
Background = new SolidColorBrush(farben[naechste++ % farben.Length]),
Child = new TextBlock { Text = text, Foreground = new SolidColorBrush(Color.FromRgb(0x1B, 0x1B, 0x1B)), Margin = new Thickness(8, 0, 8, 0), VerticalAlignment = VerticalAlignment.Center },
};
TextBlock Ueberschrift(string text) => new() { Text = text, FontWeight = 600, Margin = new Thickness(0, 8, 0, 0) };
// StackPanel: waagrecht mit Abstand.
var stapel = new StackPanel { Orientation = Orientation.Horizontal, Spacing = 8 };
for (int i = 1; i <= 4; i++) stapel.Children.Add(Feld($"Kind {i}"));
// WrapPanel: eine Schaltfläche fügt Kinder hinzu, bis umgebrochen wird.
var umbruch = new WrapPanel { Width = 420, HorizontalAlignment = HorizontalAlignment.Left };
int anzahl = 0;
void NeuesKind()
{
var kind = Feld($"Nr. {++anzahl}", 90);
kind.Margin = new Thickness(0, 0, 8, 8);
umbruch.Children.Add(kind);
}
for (int i = 0; i < 5; i++) NeuesKind();
var hinzu = new Button { Content = "Kind hinzufügen" };
hinzu.Click += (_, _) => NeuesKind();
// DockPanel: oben, links, unten, das letzte Kind füllt den Rest.
var dock = new DockPanel { Width = 420, Height = 160, HorizontalAlignment = HorizontalAlignment.Left };
var oben = Feld("Oben");
DockPanel.SetDock(oben, Dock.Top);
var links = Feld("Links", 80, double.NaN);
DockPanel.SetDock(links, Dock.Left);
var unten = Feld("Unten");
DockPanel.SetDock(unten, Dock.Bottom);
dock.Children.Add(oben);
dock.Children.Add(links);
dock.Children.Add(unten);
dock.Children.Add(Feld("Rest (füllt)", double.NaN, double.NaN));
// Grid: Spalten Auto | 1* | 2*, Zeilen Pixel und Stern, ein Kind über zwei Spalten.
var gitter = new Grid { Width = 420, Height = 120, HorizontalAlignment = HorizontalAlignment.Left };
gitter.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto });
gitter.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Star() });
gitter.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Star(2) });
gitter.RowDefinitions.Add(new RowDefinition { Height = GridLength.Pixel(40) });
gitter.RowDefinitions.Add(new RowDefinition { Height = GridLength.Star() });
void Zelle(string text, int zeile, int spalte, int spanne = 1)
{
var feld = Feld(text, double.NaN, double.NaN);
feld.Margin = new Thickness(2);
Grid.SetRow(feld, zeile);
Grid.SetColumn(feld, spalte);
Grid.SetColumnSpan(feld, spanne);
gitter.Children.Add(feld);
}
Zelle("Auto", 0, 0);
Zelle("1*", 0, 1);
Zelle("2*", 0, 2);
Zelle("Zeile 2", 1, 0);
Zelle("über zwei Spalten", 1, 1, 2);
// Canvas: feste Koordinaten, auch von rechts unten.
var flaeche = new Canvas { Width = 420, Height = 100, HorizontalAlignment = HorizontalAlignment.Left, Background = new SolidColorBrush(Color.FromArgb(0x20, 0x80, 0x80, 0x80)) };
var a = Feld("Left 10, Top 10");
Canvas.SetLeft(a, 10);
Canvas.SetTop(a, 10);
var b = Feld("Right 10, Bottom 10");
Canvas.SetRight(b, 10);
Canvas.SetBottom(b, 10);
flaeche.Children.Add(a);
flaeche.Children.Add(b);
var seite = new StackPanel { Spacing = 8 };
seite.Children.Add(Ueberschrift("StackPanel"));
seite.Children.Add(stapel);
seite.Children.Add(Ueberschrift("WrapPanel"));
seite.Children.Add(umbruch);
seite.Children.Add(hinzu);
seite.Children.Add(Ueberschrift("DockPanel"));
seite.Children.Add(dock);
seite.Children.Add(Ueberschrift("Grid"));
seite.Children.Add(gitter);
seite.Children.Add(Ueberschrift("Canvas"));
seite.Children.Add(flaeche);
return seite;
}
}