UniformGrid
Ein Raster aus lauter gleich grossen Zellen, gefüllt von links oben, Zeile für Zeile. Rows und Columns legen die Zellen fest (0 heisst automatisch: ohne beide wird es quadratisch), FirstColumn lässt am Anfang der ersten Zeile Zellen leer. Ausgeblendete Kinder belegen keine Zelle. Probieren Sie die drei Regler am Tastenfeld.


KXAML
UniformGridSeite.kxaml
<StackPanel xmlns="https://ui.kuonen.org/kxaml"
xmlns:x="https://ui.kuonen.org/kxaml/x"
x:Class="Kuonen.UI.Galerie.Seiten.UniformGridVorfuehrung"
Spacing="8">
<!-- Das Tastenfeld: vier Spalten, die Zeilen ergeben sich aus der Zahl der Tasten. Zu viele Zeilen oder Spalten werden abgeschnitten. -->
<UniformGrid x:Name="Raster" Columns="4" Width="280" Height="240" HorizontalAlignment="Left" ClipToBounds="True">
<Button Content="7" Margin="2" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />
<Button Content="8" Margin="2" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />
<Button Content="9" Margin="2" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />
<Button Content="÷" Margin="2" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />
<Button Content="4" Margin="2" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />
<Button Content="5" Margin="2" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />
<Button Content="6" Margin="2" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />
<Button Content="×" Margin="2" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />
<Button Content="1" Margin="2" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />
<Button Content="2" Margin="2" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />
<Button Content="3" Margin="2" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />
<Button Content="−" Margin="2" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />
<Button Content="0" Margin="2" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />
<Button Content="," Margin="2" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />
<Button Content="=" Margin="2" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />
<Button Content="+" Margin="2" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />
</UniformGrid>
<TextBlock x:Name="Stand" Text="Rows 0 (automatisch), Columns 4, FirstColumn 0" />
<TextBlock Text="Rows (Zeilen, 0 = automatisch)" FontWeight="SemiBold" />
<Slider Maximum="6" Value="0" SmallChange="1" LargeChange="1" TickFrequency="1" TickPlacement="BottomRight" IsSnapToTickEnabled="True"
Width="240" HorizontalAlignment="Left" ValueChanged="Zeilen_ValueChanged" />
<TextBlock Text="Columns (Spalten, 0 = automatisch)" FontWeight="SemiBold" />
<Slider Maximum="6" Value="4" SmallChange="1" LargeChange="1" TickFrequency="1" TickPlacement="BottomRight" IsSnapToTickEnabled="True"
Width="240" HorizontalAlignment="Left" ValueChanged="Spalten_ValueChanged" />
<TextBlock Text="FirstColumn (leere Zellen am Anfang; wirkt nur mit Columns > 0)" FontWeight="SemiBold" />
<Slider Maximum="5" Value="0" SmallChange="1" LargeChange="1" TickFrequency="1" TickPlacement="BottomRight" IsSnapToTickEnabled="True"
Width="240" HorizontalAlignment="Left" ValueChanged="Erste_ValueChanged" />
</StackPanel>UniformGridSeite.kxaml.cs
using Kuonen.UI;
using Kuonen.UI.Controls;
namespace Kuonen.UI.Galerie.Seiten;
public sealed partial class UniformGridSeite
{
protected override Func<UIElement>? KxamlFabrik => () => new UniformGridVorfuehrung();
}
/// <summary>KXAML-Fassung der UniformGrid-Seite: der Baum steht in UniformGridSeite.kxaml, hier nur das Verhalten.</summary>
public sealed partial class UniformGridVorfuehrung
{
public UniformGridVorfuehrung() => InitializeComponent();
private void Zeige() =>
Stand.Text = $"Rows {Raster.Rows}{(Raster.Rows == 0 ? " (automatisch)" : "")}, Columns {Raster.Columns}{(Raster.Columns == 0 ? " (automatisch)" : "")}, FirstColumn {Raster.FirstColumn}";
private void Zeilen_ValueChanged(object? sender, WertGeaendertArgs e)
{
Raster.Rows = (int)Math.Round(e.Neu);
Zeige();
}
private void Spalten_ValueChanged(object? sender, WertGeaendertArgs e)
{
Raster.Columns = (int)Math.Round(e.Neu);
Zeige();
}
private void Erste_ValueChanged(object? sender, WertGeaendertArgs e)
{
Raster.FirstColumn = (int)Math.Round(e.Neu);
Zeige();
}
}C#
UniformGridSeite.cs
using Kuonen.UI;
using Kuonen.UI.Controls;
using Kuonen.UI.Layout;
namespace Kuonen.UI.Galerie.Seiten;
/// <summary>Galerie-Seite: <see cref="UniformGrid"/>.</summary>
public sealed partial class UniformGridSeite : GalerieSeite
{
public override string Titel => "UniformGrid";
public override string Beschreibung =>
"Ein Raster aus lauter gleich grossen Zellen, gefüllt von links oben, Zeile für Zeile. Rows und Columns legen die Zellen fest "
+ "(0 heisst automatisch: ohne beide wird es quadratisch), FirstColumn lässt am Anfang der ersten Zeile Zellen leer. "
+ "Ausgeblendete Kinder belegen keine Zelle. Probieren Sie die drei Regler am Tastenfeld.";
public override string Stichworte => "Raster Zellen gleich gross Rows Columns FirstColumn Tastenfeld Rechner Zeilen Spalten GridLayout";
public override string Datei => nameof(UniformGridSeite);
public override UIElement Baue()
{
string[] tasten = ["7", "8", "9", "÷", "4", "5", "6", "×", "1", "2", "3", "−", "0", ",", "=", "+"];
// Das Tastenfeld: vier Spalten, die Zeilen ergeben sich aus der Zahl der Tasten. Zu viele Zeilen oder Spalten werden abgeschnitten.
var raster = new UniformGrid { Columns = 4, Width = 280, Height = 240, HorizontalAlignment = HorizontalAlignment.Left, ClipToBounds = true };
foreach (string taste in tasten)
raster.Children.Add(new Button { Content = taste, Margin = new Thickness(2), HorizontalAlignment = HorizontalAlignment.Stretch, VerticalAlignment = VerticalAlignment.Stretch });
var stand = new TextBlock { Text = "Rows 0 (automatisch), Columns 4, FirstColumn 0" };
void Zeige() => stand.Text = $"Rows {raster.Rows}{(raster.Rows == 0 ? " (automatisch)" : "")}, Columns {raster.Columns}{(raster.Columns == 0 ? " (automatisch)" : "")}, FirstColumn {raster.FirstColumn}";
Slider Regler(int hoechstens, int start) => new()
{
Maximum = hoechstens, Value = start, SmallChange = 1, LargeChange = 1, TickFrequency = 1, TickPlacement = TickPlacement.BottomRight,
IsSnapToTickEnabled = true, Width = 240, HorizontalAlignment = HorizontalAlignment.Left,
};
var zeilen = Regler(6, 0);
zeilen.ValueChanged += (_, e) =>
{
raster.Rows = (int)Math.Round(e.Neu);
Zeige();
};
var spalten = Regler(6, 4);
spalten.ValueChanged += (_, e) =>
{
raster.Columns = (int)Math.Round(e.Neu);
Zeige();
};
var erste = Regler(5, 0);
erste.ValueChanged += (_, e) =>
{
raster.FirstColumn = (int)Math.Round(e.Neu);
Zeige();
};
var seite = new StackPanel { Spacing = 8 };
seite.Children.Add(raster);
seite.Children.Add(stand);
seite.Children.Add(new TextBlock { Text = "Rows (Zeilen, 0 = automatisch)", FontWeight = 600 });
seite.Children.Add(zeilen);
seite.Children.Add(new TextBlock { Text = "Columns (Spalten, 0 = automatisch)", FontWeight = 600 });
seite.Children.Add(spalten);
seite.Children.Add(new TextBlock { Text = "FirstColumn (leere Zellen am Anfang; wirkt nur mit Columns > 0)", FontWeight = 600 });
seite.Children.Add(erste);
return seite;
}
}