Zum Inhalt
Kuonen.UI

MAUI-Bausteine

Stepper, ImageButton, BoxView, IndicatorView an einem Carousel und Optionsfelder, die ein Behälter gruppiert (RadioButtonGroup).

Vorführung: MAUI-BausteineVorführung: MAUI-Bausteine

KXAML

MauiKleineSeite.kxaml
<StackPanel xmlns="https://ui.kuonen.org/kxaml"
            xmlns:x="https://ui.kuonen.org/kxaml/x"
            x:Class="Kuonen.UI.Galerie.Seiten.MauiKleineVorfuehrung"
            Spacing="8">
  <!-- Gefüllt von MauiKleineSeite.Fuelle, derselben Methode wie die C#-Fassung. -->
  <StackPanel x:Name="Flaeche" Spacing="8" />
</StackPanel>
MauiKleineSeite.kxaml.cs
using Kuonen.UI;

namespace Kuonen.UI.Galerie.Seiten;

public sealed partial class MauiKleineSeite
{
    protected override Func<UIElement>? KxamlFabrik => () => new MauiKleineVorfuehrung();
}

/// <summary>KXAML-Fassung der Seite: das Gerüst steht in MauiKleineSeite.kxaml, das Innere füllt MauiKleineSeite.Fuelle.</summary>
public sealed partial class MauiKleineVorfuehrung
{
    public MauiKleineVorfuehrung()
    {
        InitializeComponent();
        MauiKleineSeite.Fuelle(Flaeche);
    }
}

C#

MauiKleineSeite.cs
using Kuonen.UI;
using Kuonen.UI.Controls;
using Kuonen.UI.Layout;
using Kuonen.UI.Media;

namespace Kuonen.UI.Galerie.Seiten;

/// <summary>Galerie-Seite: Stepper, ImageButton, BoxView, IndicatorView und RadioButtonGroup wie MAUI (Plan 6n).</summary>
public sealed partial class MauiKleineSeite : GalerieSeite
{
    public override string Titel => "MAUI-Bausteine";

    public override string Beschreibung => "Stepper, ImageButton, BoxView, IndicatorView an einem Carousel und Optionsfelder, die ein Behälter gruppiert (RadioButtonGroup).";

    public override string Stichworte => "MAUI Xamarin Stepper ImageButton BoxView IndicatorView Carousel RadioButtonGroup GroupName Punkte";

    public override string Datei => nameof(MauiKleineSeite);

    public override UIElement Baue()
    {
        // Wie die KXAML-Fassung: eine Wurzel mit der Fläche darin.
        var flaeche = new StackPanel { Spacing = 8 };
        Fuelle(flaeche);
        return new StackPanel { Spacing = 8, Children = { flaeche } };
    }

    // Ein kleines Bild aus Pixeln: ein grüner Haken auf Weiss (keine Bilddatei nötig).
    private static BitmapSource Haken()
    {
        const int n = 16;
        var pixel = new uint[n * n];
        Array.Fill(pixel, 0xFFFFFFFFu);
        for (int x = 2; x < n - 2; x++)
        {
            int y = x < 6 ? 8 + (x - 2) : 12 - (x - 6); // ein Haken: kurz hinunter, lang hinauf
            for (int d = 0; d < 2; d++)
            {
                int yy = Math.Clamp(y + d, 0, n - 1);
                pixel[yy * n + x] = 0xFF43A047u;
            }
        }
        return BitmapSource.Create(n, n, pixel);
    }

    /// <summary>Inhalt der Seite (auch von der KXAML-Fassung benutzt).</summary>
    public static void Fuelle(StackPanel flaeche)
    {
        var menge = new TextBlock { VerticalAlignment = VerticalAlignment.Center };
        var stepper = new Stepper { Maximum = 10, Value = 3 };
        menge.Text = "Menge: 3";
        stepper.ValueChanged += (_, e) => menge.Text = $"Menge: {e.Neu}";
        flaeche.Children.Add(new TextBlock { Text = "Stepper" });
        flaeche.Children.Add(new HorizontalStackLayout { Spacing = 12, Children = { stepper, menge } });

        var geklickt = new TextBlock { VerticalAlignment = VerticalAlignment.Center, Text = "Noch nicht geklickt" };
        var bildknopf = new ImageButton { Source = Haken(), Width = 48, Height = 48, Padding = new Thickness(8) };
        bildknopf.Automation.Name = "Bestätigen";
        int klicks = 0;
        bildknopf.Clicked += (_, _) => geklickt.Text = $"{++klicks}× geklickt";
        flaeche.Children.Add(new TextBlock { Text = "ImageButton" });
        flaeche.Children.Add(new HorizontalStackLayout { Spacing = 12, Children = { bildknopf, geklickt } });

        flaeche.Children.Add(new TextBlock { Text = "BoxView" });
        flaeche.Children.Add(new HorizontalStackLayout
        {
            Spacing = 8,
            Children =
            {
                new BoxView { Color = new SolidColorBrush(Color.FromRgb(0xE5, 0x39, 0x35)) },
                new BoxView { Color = new SolidColorBrush(Color.FromRgb(0x1E, 0x88, 0xE5)), CornerRadius = new CornerRadius(20) },
                new BoxView { Color = new SolidColorBrush(Color.FromRgb(0x43, 0xA0, 0x47)), Width = 100, Height = 20, CornerRadius = new CornerRadius(4) },
            },
        });

        var karussell = new Carousel { Height = 80 };
        foreach (var text in new[] { "Erste Seite", "Zweite Seite", "Dritte Seite", "Vierte Seite" })
            karussell.Items.Add(new Border { Padding = new Thickness(16), Child = new TextBlock { Text = text } });
        var punkte = new IndicatorView { IndicatorSize = 8 };
        karussell.IndicatorView = punkte;
        flaeche.Children.Add(new TextBlock { Text = "IndicatorView an einem Carousel" });
        flaeche.Children.Add(new Border { BorderThickness = new Thickness(1), Child = karussell });
        flaeche.Children.Add(punkte);

        var farben = new VerticalStackLayout { Spacing = 4 };
        RadioButtonGroup.SetGroupName(farben, "farbe");
        var gewaehlt = new TextBlock { Text = "Farbe: keine" };
        foreach (var name in new[] { "Rot", "Grün", "Blau" })
        {
            var feld = new RadioButton { Content = name };
            feld.Checked += (_, _) => gewaehlt.Text = "Farbe: " + name;
            // Jedes Feld in einem eigenen Rahmen: gruppiert sind sie über den Behälter, nicht als Geschwister.
            farben.Children.Add(new Border { Child = feld });
        }
        flaeche.Children.Add(new TextBlock { Text = "RadioButtonGroup.GroupName" });
        flaeche.Children.Add(farben);
        flaeche.Children.Add(gewaehlt);
    }
}