Zum Inhalt
Kuonen.UI

Komponenten (WinForms, WPF)

PictureBox mit SizeMode, ErrorProvider mit Fehlersymbol und Blinken, HelpProvider mit F1, dazu Adorner (WPF) als Rahmen über einem Element und der VisualStateManager.

Vorführung: Komponenten (WinForms, WPF)Vorführung: Komponenten (WinForms, WPF)

KXAML

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

namespace Kuonen.UI.Galerie.Seiten;

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

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

C#

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

namespace Kuonen.UI.Galerie.Seiten;

/// <summary>Galerie-Seite: Komponenten (WinForms, WPF) (Plan 6m).</summary>
public sealed partial class WinFormsKomponentenSeite : GalerieSeite
{
    public override string Titel => "Komponenten (WinForms, WPF)";

    public override string Beschreibung => "PictureBox mit SizeMode, ErrorProvider mit Fehlersymbol und Blinken, HelpProvider mit F1, dazu Adorner (WPF) als Rahmen über einem Element und der VisualStateManager.";

    public override string Stichworte => "PictureBox SizeMode ErrorProvider HelpProvider F1 Adorner AdornerLayer VisualStateManager VisualState WinForms WPF";

    public override string Datei => nameof(WinFormsKomponentenSeite);

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

    private static Button Knopf(string text, Action tun)
    {
        var k = new Button { Content = text };
        k.Click += (_, _) => tun();
        return k;
    }

    private static StackPanel Zeile(params UIElement[] kinder)
    {
        var z = new StackPanel { Orientation = Orientation.Horizontal, Spacing = 6 };
        foreach (var k in kinder) z.Children.Add(k);
        return z;
    }

    /// <summary>Inhalt der Seite (auch von der KXAML-Fassung benutzt).</summary>
    public static void Fuelle(StackPanel flaeche)
    {
        var bild = new PictureBox { Image = Beispielbild(), Width = 160, Height = 90, SizeMode = PictureBoxSizeMode.Zoom, BorderStyle = BorderStyle.FixedSingle, HorizontalAlignment = HorizontalAlignment.Left };
        flaeche.Children.Add(Zeile(
            Knopf("Normal", () => bild.SizeMode = PictureBoxSizeMode.Normal),
            Knopf("Strecken", () => bild.SizeMode = PictureBoxSizeMode.StretchImage),
            Knopf("Mitte", () => bild.SizeMode = PictureBoxSizeMode.CenterImage),
            Knopf("Zoom", () => bild.SizeMode = PictureBoxSizeMode.Zoom)));
        flaeche.Children.Add(bild);

        var name = new TextBox { Width = 220, HorizontalAlignment = HorizontalAlignment.Left };
        var fehler = new ErrorProvider();
        var hilfe = new HelpProvider();
        hilfe.SetHelpString(name, "Den Namen des Kunden eingeben (Pflichtfeld).");
        flaeche.Children.Add(new TextBlock { Text = "Name (F1 zeigt die Hilfe):" });
        flaeche.Children.Add(name);
        flaeche.Children.Add(Zeile(
            Knopf("Prüfen", () => fehler.SetError(name, string.IsNullOrWhiteSpace(name.Text) ? "Der Name fehlt." : "")),
            Knopf("Rahmen (Adorner)", () =>
            {
                if (AdornerLayer.GetAdornerLayer(name) is { } ebene) ebene.Add(new Markierung(name));
            })));
    }

    // Ein kleines Bild (4 × 2 Pixel, farbig), damit die Seite ohne Datei auskommt.
    private static BitmapSource Beispielbild() => BitmapSource.Create(4, 2,
        [0xFFE81123, 0xFFFFB900, 0xFF107C10, 0xFF0078D4, 0xFF0078D4, 0xFF107C10, 0xFFFFB900, 0xFFE81123]);

    /// <summary>Ein Rahmen als Schmuck über einem Element (WPF-Adorner).</summary>
    private sealed class Markierung(UIElement element) : Adorner(element)
    {
        protected override void OnRender(DrawingContext dc) =>
            dc.DrawRectangle(null, new Pen(new SolidColorBrush(Color.FromRgb(0xE8, 0x11, 0x23)), 2), new Rect(-3, -3, Bounds.Width + 6, Bounds.Height + 6));
    }
}