Zum Inhalt
Kuonen.UI

Verweise

Hyperlink steht als Inline im Fliesstext (Tab, Enter, Hand als Zeiger, Rolle Verweis für Bildschirmleser), HyperlinkButton ist eine Schaltfläche in Gestalt eines Links mit IsVisited, LinkLabel setzt Links in einen Text (Links, LinkArea, LinkClicked). Ein Klick meldet erst RequestNavigate, dann Click, dann den Befehl; diese Seite behandelt RequestNavigate und nennt die Adresse, öffnet aber nichts. Ohne Handler öffnet die Anwendung die Adresse nur, wenn sie Anwendung.VerweisOeffner setzt, und nur für http, https und mailto.

Vorführung: VerweiseVorführung: Verweise

KXAML

VerweisSeite.kxaml
<StackPanel xmlns="https://ui.kuonen.org/kxaml"
            xmlns:x="https://ui.kuonen.org/kxaml/x"
            x:Class="Kuonen.UI.Galerie.Seiten.VerweisVorfuehrung"
            Hyperlink.RequestNavigate="Seite_RequestNavigate"
            Spacing="16">
  <StackPanel Spacing="6">
    <TextBlock Text="Hyperlink im Fliesstext" FontWeight="SemiBold" />
    <!-- Ein Link mit Adresse (NavigateUri als Uri-Text) und ein Link mit Befehl (der Befehl steht im Code-Behind). -->
    <TextBlock TextWrapping="Wrap" MaxWidth="460">
      <Run Text="Mehr steht " />
      <Hyperlink NavigateUri="https://example.org/kuonen-ui"><Run Text="auf der Projektseite" /></Hyperlink>
      <Run Text=", und dieser Link hat keine Adresse, sondern einen Befehl: " />
      <Hyperlink x:Name="MitBefehl"><Run Text="Befehl ausführen" /></Hyperlink>
      <Run Text="." />
    </TextBlock>
    <TextBlock x:Name="BefehlText" Text="Befehl noch nicht ausgeführt." />
  </StackPanel>
  <StackPanel Spacing="6">
    <TextBlock Text="HyperlinkButton" FontWeight="SemiBold" />
    <StackPanel Orientation="Horizontal" Spacing="8">
      <HyperlinkButton x:Name="Knopf" Content="Zur Dokumentation" NavigateUri="https://example.org/doku" Click="Knopf_Click" />
      <Button Content="Zurücksetzen" Click="Zuruecksetzen_Click" />
    </StackPanel>
    <TextBlock x:Name="BesuchtText" Text="Besucht: nein" />
  </StackPanel>
  <StackPanel Spacing="6">
    <TextBlock Text="LinkLabel" FontWeight="SemiBold" />
    <!-- Die drei Links stehen im Code-Behind (LinkArea ist kein Attributwert). -->
    <LinkLabel x:Name="Etikett" Text="Hilfe, Datenschutz oder Impressum" LinkClicked="Etikett_LinkClicked" />
    <TextBlock x:Name="EtikettText" Text="LinkClicked: noch nichts." />
  </StackPanel>
  <StackPanel Spacing="6">
    <TextBlock Text="Meldung der Seite" FontWeight="SemiBold" />
    <TextBlock x:Name="Meldung" Text="Angefordert: noch nichts." TextWrapping="Wrap" />
  </StackPanel>
</StackPanel>
VerweisSeite.kxaml.cs
using Kuonen.UI;
using Kuonen.UI.Befehle;
using Kuonen.UI.Controls;
using Kuonen.UI.Ereignisse;

namespace Kuonen.UI.Galerie.Seiten;

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

/// <summary>KXAML-Fassung der Verweis-Seite: der Baum steht in VerweisSeite.kxaml, hier nur das Verhalten.</summary>
public sealed partial class VerweisVorfuehrung
{
    private int _befehle;

    public VerweisVorfuehrung()
    {
        InitializeComponent();
        MitBefehl.Command = new RelayCommand(() => BefehlText.Text = "Befehl " + (++_befehle) + "-mal ausgeführt.");
        Etikett.Links.Add(0, 5, "Hilfe");
        Etikett.Links.Add(7, 11, "Datenschutz");
        Etikett.Links.Add(24, 9, "Impressum");
    }

    // Die Seite behandelt jede angeforderte Adresse selbst: sie nennt sie und öffnet nichts (Handled).
    private void Seite_RequestNavigate(object sender, RequestNavigateEventArgs e)
    {
        Meldung.Text = "Angefordert: " + e.Uri.AbsoluteUri;
        e.Handled = true;
    }

    private void Knopf_Click(object sender, RoutedEventArgs e) => BesuchtText.Text = Knopf.IsVisited ? "Besucht: ja" : "Besucht: nein";

    private void Zuruecksetzen_Click(object sender, RoutedEventArgs e)
    {
        Knopf.IsVisited = false;
        BesuchtText.Text = "Besucht: nein";
    }

    private void Etikett_LinkClicked(object? sender, LinkLabelLinkClickedEventArgs e)
    {
        e.Link.Visited = true;
        EtikettText.Text = "LinkClicked: " + e.Link.LinkData + " (besucht).";
    }
}

C#

VerweisSeite.cs
using Kuonen.UI;
using Kuonen.UI.Befehle;
using Kuonen.UI.Controls;
using Kuonen.UI.Layout;

namespace Kuonen.UI.Galerie.Seiten;

/// <summary>Galerie-Seite: <see cref="Hyperlink"/>, <see cref="HyperlinkButton"/> und <see cref="LinkLabel"/>.</summary>
public sealed partial class VerweisSeite : GalerieSeite
{
    public override string Titel => "Verweise";

    public override string Beschreibung =>
        "Hyperlink steht als Inline im Fliesstext (Tab, Enter, Hand als Zeiger, Rolle Verweis für Bildschirmleser), "
        + "HyperlinkButton ist eine Schaltfläche in Gestalt eines Links mit IsVisited, LinkLabel setzt Links in einen Text "
        + "(Links, LinkArea, LinkClicked). Ein Klick meldet erst RequestNavigate, dann Click, dann den Befehl; diese Seite behandelt "
        + "RequestNavigate und nennt die Adresse, öffnet aber nichts. Ohne Handler öffnet die Anwendung die Adresse nur, wenn sie "
        + "Anwendung.VerweisOeffner setzt, und nur für http, https und mailto.";

    public override string Stichworte => "Hyperlink HyperlinkButton LinkLabel Link Verweis URL Adresse NavigateUri RequestNavigate IsVisited LinkArea LinkClicked";

    public override string Datei => nameof(VerweisSeite);

    public override UIElement Baue()
    {
        var meldung = new TextBlock { Text = "Angefordert: noch nichts.", TextWrapping = TextWrapping.Wrap };
        var befehlText = new TextBlock { Text = "Befehl noch nicht ausgeführt." };
        var besuchtText = new TextBlock { Text = "Besucht: nein" };
        var etikettText = new TextBlock { Text = "LinkClicked: noch nichts." };

        // Fliesstext: ein Link mit Adresse, ein Link mit Befehl.
        int befehle = 0;
        var mitAdresse = new Hyperlink(new Run("auf der Projektseite")) { NavigateUri = new Uri("https://example.org/kuonen-ui") };
        var mitBefehl = new Hyperlink(new Run("Befehl ausführen"))
        {
            Command = new RelayCommand(() => befehlText.Text = "Befehl " + (++befehle) + "-mal ausgeführt."),
        };
        var fliesstext = new TextBlock { TextWrapping = TextWrapping.Wrap, MaxWidth = 460 };
        fliesstext.Inlines.Add(new Run("Mehr steht "));
        fliesstext.Inlines.Add(mitAdresse);
        fliesstext.Inlines.Add(new Run(", und dieser Link hat keine Adresse, sondern einen Befehl: "));
        fliesstext.Inlines.Add(mitBefehl);
        fliesstext.Inlines.Add(new Run("."));

        // HyperlinkButton: IsVisited wird beim Auslösen wahr.
        var knopf = new HyperlinkButton { Content = "Zur Dokumentation", NavigateUri = new Uri("https://example.org/doku") };
        knopf.Click += (_, _) => besuchtText.Text = knopf.IsVisited ? "Besucht: ja" : "Besucht: nein";
        var zuruecksetzen = new Button { Content = "Zurücksetzen" };
        zuruecksetzen.Click += (_, _) =>
        {
            knopf.IsVisited = false;
            besuchtText.Text = "Besucht: nein";
        };
        var knopfZeile = new StackPanel { Orientation = Orientation.Horizontal, Spacing = 8 };
        knopfZeile.Children.Add(knopf);
        knopfZeile.Children.Add(zuruecksetzen);

        // LinkLabel: drei Links in einem Text; was geschieht, entscheidet der Handler (hier: besucht setzen und melden).
        var etikett = new LinkLabel { Text = "Hilfe, Datenschutz oder Impressum" };
        etikett.Links.Add(0, 5, "Hilfe");
        etikett.Links.Add(7, 11, "Datenschutz");
        etikett.Links.Add(24, 9, "Impressum");
        etikett.LinkClicked += (_, e) =>
        {
            e.Link.Visited = true;
            etikettText.Text = "LinkClicked: " + e.Link.LinkData + " (besucht).";
        };

        StackPanel Gruppe(string titel, params UIElement[] inhalt)
        {
            var g = new StackPanel { Spacing = 6 };
            g.Children.Add(new TextBlock { Text = titel, FontWeight = 600 });
            foreach (var element in inhalt) g.Children.Add(element);
            return g;
        }

        var wurzel = new StackPanel { Spacing = 16 };
        wurzel.Children.Add(Gruppe("Hyperlink im Fliesstext", fliesstext, befehlText));
        wurzel.Children.Add(Gruppe("HyperlinkButton", knopfZeile, besuchtText));
        wurzel.Children.Add(Gruppe("LinkLabel", etikett, etikettText));
        wurzel.Children.Add(Gruppe("Meldung der Seite", meldung));
        // Die Seite behandelt jede angeforderte Adresse selbst: sie nennt sie und öffnet nichts (Handled).
        wurzel.AddHandler(Hyperlink.RequestNavigateEvent, (object _, RequestNavigateEventArgs e) =>
        {
            meldung.Text = "Angefordert: " + e.Uri.AbsoluteUri;
            e.Handled = true;
        });
        return wurzel;
    }
}