Zum Inhalt
Kuonen.UI

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.

Vorführung: UniformGridVorführung: UniformGrid

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 &gt; 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;
    }
}