Home > database >  .net maui add objects to canvas on runtime
.net maui add objects to canvas on runtime

Time:11-21

Lets say I have very simple xaml

<?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:drawable="clr-namespace:eden.Pages"
             x:Class="eden.Pages.Modeler">
    <ContentPage.Resources>
    <drawable:GraphicsDrawable x:Key="drawable" />
</ContentPage.Resources>
    <VerticalStackLayout>
        <GraphicsView x:Name="modelerArea"
            Drawable="{StaticResource drawable}">
            <FlyoutBase.ContextFlyout>
                <MenuFlyout>
                    <MenuFlyoutItem Text="Add rectangle"
                            Clicked="AddRectangle"> <!-- HERE I WANT TO ADD RECTANGLE ON CLICK -->
                    </MenuFlyoutItem>
                </MenuFlyout>
            </FlyoutBase.ContextFlyout>
        </GraphicsView>
    </VerticalStackLayout>
</ContentPage>

And then very simple xaml.cs

public partial class Modeler : ContentPage
    {
        public Modeler()
        {
            InitializeComponent();
        }

        private void AddRectangle(object sender, EventArgs e)
        {
           // for example
           // var mySpecialRectangle = new specialRectangle();
           // canvas.Add(mySpecialRectangle);
        }
    }

    public class GraphicsDrawable : IDrawable
    {
        public void Draw(ICanvas canvas, RectF dirtyRect)
        {
            canvas.StrokeColor = Colors.Red;
            canvas.StrokeSize = 6;
            canvas.DrawLine(10, 10, 90, 100);
        }
    }
}

How can I add that object to canvas/graphicsview?

CodePudding user response:

Have you read Draw graphical objects?

You don't "add objects" in the ICanvas approach. Rather, you make "draw" calls.

modelerArea is canvas in your xaml, so it will be variations on:

public void MyDrawLine(ICanvas canvas, ...)
{
    canvas.DrawLine(...);
}

...
MyDrawLine(modelerArea, ...);

Caveat: I've never done this myself; I'm basing this on the linked doc.

An implication is that if you want to "remember" some "objects" for later, you'll have to do that yourself. Define your own class that describes an object to draw. Maintain a list of those object "models", so you can draw them all later.

CodePudding user response:

The rectangle is drawing in the graphicsview. So you can create a class inherited from the IDrawable and then set it as the Drawable property of the instance of the GraphicsView. Finally, you can add the instance of the GraphicsView into the layout. Such as:

In the page.xaml:

<VerticalStackLayout
            Spacing="25"
            Padding="30,0"
            VerticalOptions="Center"
        x:Name="layout">
        <Button
                x:Name="CounterBtn"
                Text="Click me"
                Clicked="OnCounterClicked" />
    </VerticalStackLayout>

In the page.cs:

public partial class MainPage : ContentPage
{

      public MainPage()
      {
            InitializeComponent();
      }
    internal class RectangleDrawable : IDrawable
    {
        public void Draw(ICanvas canvas, RectF dirtyRect)
        {
            canvas.StrokeColor = Colors.DarkBlue;
            canvas.StrokeSize = 4;
            canvas.DrawRectangle(10, 10, 100, 50);
        }
    }
    private void OnCounterClicked(object sender, EventArgs e)
      {
            
            GraphicsView graphicsView = new GraphicsView();
            graphicsView.Drawable = new RectangleDrawable();
        graphicsView.HeightRequest= 200;
        graphicsView.WidthRequest = 400;
        layout.Children.Add(graphicsView);
      }
}

The Rectangle will be drawn when you clicked the button.

  • Related