MAUI-Zeichnen und Gesten
GraphicsView mit IDrawable und ICanvas; Tippen, Doppeltippen, Verschieben und Wischen über Gestenerkenner wie MAUI.


KXAML
MauiZeichnenSeite.kxaml
<StackPanel xmlns="https://ui.kuonen.org/kxaml"
xmlns:x="https://ui.kuonen.org/kxaml/x"
x:Class="Kuonen.UI.Galerie.Seiten.MauiZeichnenVorfuehrung"
Spacing="8">
<!-- Gefüllt von MauiZeichnenSeite.Fuelle, derselben Methode wie die C#-Fassung. -->
<StackPanel x:Name="Flaeche" Spacing="8" />
</StackPanel>MauiZeichnenSeite.kxaml.cs
using Kuonen.UI;
namespace Kuonen.UI.Galerie.Seiten;
public sealed partial class MauiZeichnenSeite
{
protected override Func<UIElement>? KxamlFabrik => () => new MauiZeichnenVorfuehrung();
}
/// <summary>KXAML-Fassung der Seite: das Gerüst steht in MauiZeichnenSeite.kxaml, das Innere füllt MauiZeichnenSeite.Fuelle.</summary>
public sealed partial class MauiZeichnenVorfuehrung
{
public MauiZeichnenVorfuehrung()
{
InitializeComponent();
MauiZeichnenSeite.Fuelle(Flaeche);
}
}C#
MauiZeichnenSeite.cs
using Kuonen.UI;
using Kuonen.UI.Controls;
using Kuonen.UI.Eingabe;
using Kuonen.UI.Layout;
using Kuonen.UI.Media;
namespace Kuonen.UI.Galerie.Seiten;
/// <summary>Galerie-Seite: GraphicsView und Gestenerkenner wie MAUI (Plan 6n).</summary>
public sealed partial class MauiZeichnenSeite : GalerieSeite
{
public override string Titel => "MAUI-Zeichnen und Gesten";
public override string Beschreibung => "GraphicsView mit IDrawable und ICanvas; Tippen, Doppeltippen, Verschieben und Wischen über Gestenerkenner wie MAUI.";
public override string Stichworte => "MAUI Xamarin GraphicsView IDrawable ICanvas TapGestureRecognizer PanGestureRecognizer SwipeGestureRecognizer Geste Tippen Wischen";
public override string Datei => nameof(MauiZeichnenSeite);
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 } };
}
/// <summary>Ein Diagramm aus Balken, gezeichnet über die ICanvas.</summary>
public sealed class Balken : IDrawable
{
public int Hervorgehoben { get; set; } = -1;
private static readonly double[] Werte = [0.4, 0.7, 0.55, 0.9, 0.3];
public void Draw(ICanvas canvas, Rect dirtyRect)
{
canvas.FillColor = Color.FromRgb(0xF2, 0xF2, 0xF2);
canvas.FillRoundedRectangle(0, 0, dirtyRect.Width, dirtyRect.Height, 8);
double breite = dirtyRect.Width / Werte.Length;
for (int i = 0; i < Werte.Length; i++)
{
canvas.FillColor = i == Hervorgehoben ? Color.FromRgb(0xE5, 0x39, 0x35) : Color.FromRgb(0x1E, 0x88, 0xE5);
double h = (dirtyRect.Height - 30) * Werte[i];
canvas.FillRectangle(i * breite + 8, dirtyRect.Height - 20 - h, breite - 16, h);
canvas.FontColor = Color.FromRgb(0x33, 0x33, 0x33);
canvas.FontSize = 11;
canvas.DrawString($"{Werte[i]:P0}", i * breite + breite / 2, dirtyRect.Height - 6, HorizontalAlignment.Center);
}
}
}
/// <summary>Inhalt der Seite (auch von der KXAML-Fassung benutzt).</summary>
public static void Fuelle(StackPanel flaeche)
{
var balken = new Balken();
var zeichnung = new GraphicsView { Drawable = balken, Width = 320, Height = 160, HorizontalAlignment = HorizontalAlignment.Left };
var tippen = new TapGestureRecognizer();
tippen.Tapped += (_, e) =>
{
if (e.GetPosition(zeichnung) is { } p) balken.Hervorgehoben = (int)(p.X / (zeichnung.Bounds.Width / 5));
zeichnung.Invalidate();
};
zeichnung.GestureRecognizers.Add(tippen);
flaeche.Children.Add(new TextBlock { Text = "GraphicsView (ein Tippen hebt einen Balken hervor)" });
flaeche.Children.Add(zeichnung);
var meldung = new TextBlock { Text = "Ziehe den Kasten, tippe doppelt oder wische." };
var kasten = new BoxView { Color = new SolidColorBrush(Color.FromRgb(0x43, 0xA0, 0x47)), Width = 60, Height = 60, CornerRadius = new CornerRadius(8) };
var spielfeld = new Canvas { Width = 320, Height = 140, Background = new SolidColorBrush(Color.FromRgb(0xF2, 0xF2, 0xF2)), HorizontalAlignment = HorizontalAlignment.Left, ClipToBounds = true };
Canvas.SetLeft(kasten, 20);
Canvas.SetTop(kasten, 40);
spielfeld.Children.Add(kasten);
double startX = 0, startY = 0;
var verschieben = new PanGestureRecognizer();
verschieben.PanUpdated += (_, e) =>
{
if (e.StatusType == GestureStatus.Started) (startX, startY) = (Canvas.GetLeft(kasten), Canvas.GetTop(kasten));
if (e.StatusType != GestureStatus.Running) return;
Canvas.SetLeft(kasten, Math.Clamp(startX + e.TotalX, 0, 260));
Canvas.SetTop(kasten, Math.Clamp(startY + e.TotalY, 0, 80));
};
var doppelt = new TapGestureRecognizer { NumberOfTapsRequired = 2 };
doppelt.Tapped += (_, _) => meldung.Text = "Doppelt getippt";
kasten.GestureRecognizers.Add(verschieben);
kasten.GestureRecognizers.Add(doppelt);
var wischen = new SwipeGestureRecognizer { Direction = SwipeDirection.Left | SwipeDirection.Right | SwipeDirection.Up | SwipeDirection.Down };
wischen.Swiped += (_, e) => meldung.Text = "Gewischt: " + e.Direction;
spielfeld.GestureRecognizers.Add(wischen);
flaeche.Children.Add(new TextBlock { Text = "Gestenerkenner" });
flaeche.Children.Add(spielfeld);
flaeche.Children.Add(meldung);
}
}