How to add to "GraphicsView" class with “DrawableProperty" in dotnet maui

康二郎 井上 20 Reputation points
2024-04-27T01:29:11.7533333+00:00

Hello!

I trying drawing of the circle in center which is touched in the "GraphicsView" control.

And I thought the one of the important points is how to add "GraphicsView" class with "DrawableProperty" in dotnet Maui.

Please teach me a sample code.

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 

            Drawable="{StaticResource drawable}"

            x:Name="graph"

            HorizontalOptions="Center"

            VerticalOptions="Start"

            HeightRequest="300" WidthRequest="300"

            StartInteraction="OnStartInteraction"

         />

        <Label

            Text="text"

            x:Name="Text"

            FontSize="10"

            HorizontalOptions="Start"

            VerticalOptions="End"

            />


    

    </VerticalStackLayout>

</ScrollView>
</ContentPage>

MainPage.xaml.cs:


namespace MauiTouch2;

public class class1

{


public PointF? pos { get; set; }
}


public partial class MainPage : ContentPage

{

private class1? test = null;

public MainPage()

{

    InitializeComponent();

}

private void OnStartInteraction(object Sender, TouchEventArgs evt)

{

    PointF firstPoint = evt.Touches.FirstOrDefault();

    string msg = $"Touch/click at {firstPoint}";

    this.test = new class1();

    this.test.pos = firstPoint;

    //graph.Invalidate();

    Text.Text = msg;

}
}
public class GraphicsDrawable : IDrawable

{

public void Draw(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);


        

        canvas.FontColor = Colors.Black;

        canvas.FontSize = 18;

    //canvas.Font = Font.Default;

        canvas.DrawString("a  b  c  d  e  f  g  h ", 0, 0, 300, 20, HorizontalAlignment.Left, VerticalAlignment.Top);

        canvas.DrawString("1", 0, 20, 20, 20, HorizontalAlignment.Right, VerticalAlignment.Top);

        canvas.DrawString("2", 0, 40, 20, 20, HorizontalAlignment.Right, VerticalAlignment.Top);

        canvas.StrokeColor = Colors.Black;

    canvas.FillColor = Colors.DarkBlue;

        canvas.FillCircle(100, 100, 80);

        canvas.StrokeColor = Colors.LightPink;

        canvas.StrokeSize = 1;

        double rad = 0;

        float x1 = 200;

        float y1 = 100;

        for (int i = 0; i < 100; i++)

        {

            float x2 = (float)(Math.Cos(rad) * 100) + 100;

            float y2 = (float)(Math.Sin(rad) * 100) + 100;

            canvas.DrawLine(x1, y1, x2, y2);

            x1 = x2;

            y1 = y2;

            rad += Math.PI * (170.0 / 180.0);

        }

    }  

  }
.NET MAUI
.NET MAUI
A Microsoft open-source framework for building native device applications spanning mobile, tablet, and desktop.
2,911 questions
C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
10,293 questions
{count} votes

Accepted answer
  1. gekka 6,846 Reputation points MVP
    2024-04-30T08:50:55.57+00:00

    What you want is to draw a circle where you touch in GraphicsView?

    <?xml version="1.0" encoding="utf-8" ?>
    <ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                 xmlns:local="clr-namespace:CSMaui"
                 x:Class="CSMaui.MainPage">
        <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>
    
    namespace CSMaui
    {
        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.AddSeconds(0.5);
                while (DateTime.Now <= end && !token.IsCancellationRequested)
                {
                    c.radius = (float)(start - DateTime.Now).TotalSeconds * 100;
                    view.Invalidate();
                    await Task.Delay(1);
                }
    
                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.Red;
                canvas.StrokeSize = 2;
                canvas.ClipRectangle(dirtyRect);
    
                HitItem[] items;
                lock (this.HitItems)
                {
                    items = this.HitItems.ToArray();
                }
    
                foreach (var item in items)
                {
                    canvas.DrawCircle(item.pos, item.radius);
                }
    
                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);
                canvas.FontColor = Colors.Black;
                canvas.FontSize = 18;
                //canvas.Font = Font.Default;
                canvas.DrawString("a b c d e f g h ", 0, 0, 300, 20, HorizontalAlignment.Left, VerticalAlignment.Top);
                canvas.DrawString("1", 0, 20, 20, 20, HorizontalAlignment.Right, VerticalAlignment.Top);
                canvas.DrawString("2", 0, 40, 20, 20, HorizontalAlignment.Right, VerticalAlignment.Top);
                canvas.StrokeColor = Colors.Black;
                canvas.FillColor = Colors.DarkBlue;
                canvas.FillCircle(100, 100, 80);
                canvas.StrokeColor = Colors.LightPink;
                canvas.StrokeSize = 1;
                double rad = 0;
                float x1 = 200;
                float y1 = 100;
                for (int i = 0; i < 100; i++)
                {
                    float x2 = (float)(Math.Cos(rad) * 100) + 100;
                    float y2 = (float)(Math.Sin(rad) * 100) + 100;
    
                    canvas.DrawLine(x1, y1, x2, y2);
    
                    x1 = x2;
                    y1 = y2;
    
                    rad += Math.PI * (170.0 / 180.0);
                }
            }
        }
    }
    

1 additional answer

Sort by: Most helpful
  1. 康二郎 井上 20 Reputation points
    2024-05-01T12:07:04.0533333+00:00

    I'd like to draw a simple circle. i correct your code as under code.

    Please teach me appropriate HitPoint data.

    public partial class MainPage : ContentPage

    {

    public MainPage()
    
    {
    
        InitializeComponent();
    
    }
    
    private  void OnStartInteraction(object sender, TouchEventArgs evt)
    
    {
    
        PointF firstPoint = evt.Touches.FirstOrDefault();
    
        string msg = $"Touch/click at {firstPoint}";
    
        Text.Text = msg;
    
        this.drawable.OnTouchAsync(this.graph, firstPoint);
    
    }
    

    }

    public class HitPoint

    {

    public PointF pos { get; set; }
    

    }

    //private HitPoint test = null;

    public class GraphicsDrawable : IDrawable

    {

       public void OnTouchAsync(IGraphicsView view, PointF point)
    
    {
    
        HitPoint c = new HitPoint();
    
        c.pos = point;
    
        view.Invalidate();
    
    }
    
    public void Draw(ICanvas canvas, RectF dirtyRect)
    
    {
    
        DrawHitPoint(canvas, dirtyRect);
    
    }
    
    private void DrawHitPoint(ICanvas canvas, RectF dirtyRect)
    
    {
    
        HitPoint c = new HitPoint();      //How  to write ?
    
        //private Point F pos1=c.pos;    //How  to write ?
    
        canvas.SaveState();
    
        canvas.StrokeColor = Colors.Red;
    
        canvas.StrokeSize = 2;
    
        canvas.ClipRectangle(dirtyRect);
    
        canvas.DrawCircle(pos1, 30);      
    
        canvas.ResetState();
    
    }
    

    }