Zum Inhalt
Kuonen.UI

Assistent

Ein Import-Assistent wie in SSMS: links die Schritte (ein Klick springt zurück), oben Titel und Beschreibung, unten Zurück, Weiter und Abbrechen. Weiter geht erst mit einer Datei, eine leere Zieltabelle hält mit einer Meldung an, „Erweiterte Optionen“ nimmt eine Seite in den Weg auf. Enter wirkt wie Weiter, Esc wie Abbrechen, Alt+Pfeile blättern.

Vorführung: AssistentVorführung: Assistent

KXAML

AssistentSeite.kxaml
<StackPanel xmlns="https://ui.kuonen.org/kxaml"
            xmlns:x="https://ui.kuonen.org/kxaml/x"
            x:Class="Kuonen.UI.Galerie.Seiten.AssistentVorfuehrung"
            Spacing="8">
  <Wizard x:Name="Import" Height="360">
    <WizardPage x:Name="Quelle" Title="Datenquelle" Description="Woher kommen die Daten?">
      <StackPanel Spacing="6">
        <TextBlock Text="Datei (CSV)" />
        <TextBox x:Name="Datei" />
      </StackPanel>
    </WizardPage>
    <WizardPage x:Name="Ziel" Title="Ziel" Description="In welche Tabelle sollen die Zeilen?">
      <StackPanel Spacing="6">
        <TextBlock Text="Zieltabelle" />
        <TextBox x:Name="Tabelle" />
      </StackPanel>
    </WizardPage>
    <WizardPage Title="Optionen">
      <StackPanel Spacing="6">
        <CheckBox Content="Vorhandene Zeilen löschen" />
        <CheckBox x:Name="Erweitert" Content="Erweiterte Optionen" />
      </StackPanel>
    </WizardPage>
    <WizardPage x:Name="ErweitertSeite" Title="Erweitert">
      <CheckBox Content="Identitätswerte übernehmen" />
    </WizardPage>
    <WizardPage Title="Zusammenfassung" Description="Fertig stellen startet den Import.">
      <TextBlock x:Name="Zusammenfassung" />
    </WizardPage>
  </Wizard>
  <TextBlock x:Name="Status" Text="Noch nichts importiert." />
</StackPanel>
AssistentSeite.kxaml.cs
using Kuonen.UI;

namespace Kuonen.UI.Galerie.Seiten;

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

/// <summary>KXAML-Fassung der Seite Assistent: der Aufbau steht in AssistentSeite.kxaml, hier das Verhalten.</summary>
public sealed partial class AssistentVorfuehrung
{
    public AssistentVorfuehrung()
    {
        InitializeComponent();
        AssistentSeite.Verdrahte(new AssistentSeite.Teile(Import, Quelle, Datei, Ziel, Tabelle, Erweitert, ErweitertSeite, Zusammenfassung, Status));
    }
}

C#

AssistentSeite.cs
using Kuonen.UI;
using Kuonen.UI.Controls;
using Kuonen.UI.Layout;

namespace Kuonen.UI.Galerie.Seiten;

/// <summary>Galerie-Seite: der Assistent (<see cref="Wizard"/>) als Import-Assistent wie in SSMS.</summary>
public sealed partial class AssistentSeite : GalerieSeite
{
    public override string Titel => "Assistent";

    public override string Beschreibung =>
        "Ein Import-Assistent wie in SSMS: links die Schritte (ein Klick springt zurück), oben Titel und Beschreibung, unten Zurück, Weiter und "
        + "Abbrechen. Weiter geht erst mit einer Datei, eine leere Zieltabelle hält mit einer Meldung an, „Erweiterte Optionen“ nimmt eine Seite in "
        + "den Weg auf. Enter wirkt wie Weiter, Esc wie Abbrechen, Alt+Pfeile blättern.";

    public override string Stichworte => "Wizard Assistent Stepper Import Export Seiten Weiter Zurück Fertig stellen Prüfung Validierung Schritte";

    public override string Datei => nameof(AssistentSeite);

    /// <summary>Die Seiten, die beide Fassungen brauchen.</summary>
    internal sealed record Teile(Wizard Wizard, WizardPage Quelle, TextBox Datei, WizardPage Ziel, TextBox Tabelle, CheckBox Erweitert,
        WizardPage ErweitertSeite, TextBlock Zusammenfassung, TextBlock Status);

    /// <summary>Das Verhalten beider Fassungen.</summary>
    internal static void Verdrahte(Teile t)
    {
        t.ErweitertSeite.IsIncluded = false;
        t.Quelle.CanGoNext = false;
        t.Datei.TextChanged += (_, _) => t.Quelle.CanGoNext = t.Datei.Text.Trim().Length > 0;
        t.Ziel.Validating += (_, e) =>
        {
            if (t.Tabelle.Text.Trim().Length == 0) (e.Cancel, e.ErrorMessage) = (true, "Bitte eine Zieltabelle angeben.");
        };
        t.Erweitert.Checked += (_, _) => t.ErweitertSeite.IsIncluded = true;
        t.Erweitert.Unchecked += (_, _) => t.ErweitertSeite.IsIncluded = false;
        t.Wizard.PageChanged += (_, _) => t.Zusammenfassung.Text =
            $"Quelle: {t.Datei.Text.Trim()}\nZiel: {t.Tabelle.Text.Trim()}\nErweiterte Optionen: {(t.Erweitert.IsChecked == true ? "ja" : "nein")}";
        t.Wizard.Finished += (_, _) => t.Status.Text = $"Importiert: {t.Datei.Text.Trim()} nach {t.Tabelle.Text.Trim()}.";
        t.Wizard.Cancelled += (_, _) => t.Status.Text = "Abgebrochen.";
    }

    public override UIElement Baue()
    {
        var datei = new TextBox();
        var quelle = new WizardPage
        {
            Title = "Datenquelle", Description = "Woher kommen die Daten?",
            Content = new StackPanel { Spacing = 6, Children = { new TextBlock { Text = "Datei (CSV)" }, datei } },
        };
        var tabelle = new TextBox();
        var ziel = new WizardPage
        {
            Title = "Ziel", Description = "In welche Tabelle sollen die Zeilen?",
            Content = new StackPanel { Spacing = 6, Children = { new TextBlock { Text = "Zieltabelle" }, tabelle } },
        };
        var erweitert = new CheckBox { Content = "Erweiterte Optionen" };
        var optionen = new WizardPage
        {
            Title = "Optionen",
            Content = new StackPanel { Spacing = 6, Children = { new CheckBox { Content = "Vorhandene Zeilen löschen" }, erweitert } },
        };
        var erweitertSeite = new WizardPage { Title = "Erweitert", Content = new CheckBox { Content = "Identitätswerte übernehmen" } };
        var zusammenfassung = new TextBlock();
        var schluss = new WizardPage { Title = "Zusammenfassung", Description = "Fertig stellen startet den Import.", Content = zusammenfassung };
        var wizard = new Wizard { Height = 360, Pages = { quelle, ziel, optionen, erweitertSeite, schluss } };
        var status = new TextBlock { Text = "Noch nichts importiert." };
        Verdrahte(new Teile(wizard, quelle, datei, ziel, tabelle, erweitert, erweitertSeite, zusammenfassung, status));
        return new StackPanel { Spacing = 8, Children = { wizard, status } };
    }
}