Search code examples
c#xamlmaui

.net maui add objects to canvas on runtime


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?


Solution

  • 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.