投稿者 kojiro  (社会人) 投稿日時 2024/5/8 16:57:20
最終的な、サンプルコードです。GraphicsViewコントロール内をクリックすると、円が描かれます。
MainPage.xaml:
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:MauiTouch2"
             x:Class="MauiTouch2.MainPage">
    <ContentPage.Resources>
        <local:GraphicsDrawable x:Key="drawable" />
    </ContentPage.Resources>
    <ScrollView>
        <VerticalStackLayout
            Spacing="25"
            Padding="30,0"
            VerticalOptions="Center">
            <GraphicsView x:Name="graph" HorizontalOptions="Center" VerticalOptions="Start" HeightRequest="300" WidthRequest="300"
                      StartInteraction="OnStartInteraction" >
                <GraphicsView.Drawable>
                    <local:GraphicsDrawable x:Name="drawable" />
                </GraphicsView.Drawable>
            </GraphicsView>
            <Label
                Text="text"
                x:Name="Text"
                FontSize="10"
                HorizontalOptions="Start"
                VerticalOptions="End"
                />
        </VerticalStackLayout>
    </ScrollView>
</ContentPage>

MainPage.xaml.cs:
 
namespace MauiTouch2;
public partial class MainPage : ContentPage
{   
    public MainPage()
    {
        InitializeComponent();
    }
    private async void OnStartInteraction(object sender, TouchEventArgs evt)
    {
        PointF firstPoint = evt.Touches.FirstOrDefault();
        string msg = $"Touch/click at {firstPoint}";
        Text.Text = msg;
        await this.drawable.OnTouchAsync(this.graph, firstPoint, CancellationToken.None);
    }
}
public class HitItem
{
    public PointF pos { get; set; }
    //public float radius { get; set; }
}

public class GraphicsDrawable : IDrawable
{
    public List<HitItem> HitItems { get; } = new List<HitItem>();
    public async Task OnTouchAsync(IGraphicsView view, PointF point, CancellationToken token)
    {
        HitItem c = new HitItem();
        c.pos = point;
        //c.radius = 0;
        //lock (this.HitItems)
        //{
           this.HitItems.Add(c);
       // }
       // DateTime start = DateTime.Now;
       // DateTime end = start.AddDays(1);
       // while ( !token.IsCancellationRequested) //DateTime.Now <= end &&
       // {
            //c.radius = 20;  // (float)(start - DateTime.Now).TotalSeconds * 100;
            view.Invalidate();
            await Task.Delay(30);
       // }

        //lock (this.HitItems)
        //{
            this.HitItems.Remove(c);
        //}

        //view.Invalidate();
    }

    public void Draw(ICanvas canvas, RectF dirtyRect)
    {
        DrawBack(canvas, dirtyRect);
        DrawHitPoint(canvas, dirtyRect);
    }

    private void DrawHitPoint(ICanvas canvas, RectF dirtyRect)
    {
        if (HitItems.Count == 0)
        {
            return;
        }
        canvas.SaveState();
        canvas.StrokeColor = Colors.Black;
        canvas.StrokeSize = 2;
        canvas.ClipRectangle(dirtyRect);
        HitItem[] items;
        lock (this.HitItems)
        {
            items = this.HitItems.ToArray();
        }
        // foreach (var item in items)
        // {
        canvas.DrawCircle(items[0].pos, 20);
       // }
        canvas.ResetState();
    }
    private void DrawBack(ICanvas canvas, RectF dirtyRect)
    {
        int x = 300;
        canvas.StrokeColor = Colors.Black;
        canvas.StrokeSize = 3;
        canvas.DrawLine(0, 0, x, 0);
        canvas.DrawLine(0, x, x, x);
        canvas.DrawLine(0, 0, 0, x);
        canvas.DrawLine(x, 0, x, x);      
    }
}