.NET Multi-platform App UI (.NET MAUI) is a framework for building modern, multi-platform, natively compiled iOS, Android, macOS, and Windows apps using C# and XAML in a single codebase [3]. This blog show how to use draw a graphical object in .NET MAUI app.

.Net MAUI provides Microsoft.Maui.Graphics namespace that allow to draw and paint shape, images, compositing operations, and transforming graphical object on a GaphicsView.

To draw graphical objects, we create a class named GraphicsDrawable which derives from IDrawable interface and implements its Draw method. All graphical objects will be drawn from this method.

namespace Graphics

{

public class GraphicsDrawable : IDrawable

{

public void Draw(ICanvas canvas, RectF rectF)

{

 // Drawing code goes here

}

}

}

In the Draw method, the ICanvas argument is used for drawing graphical objects and another for specifying size and location of the drawing canvas.

Next, we define a ContentPage.Resource that contains object of class GraphicsDrawable and a GraphicsView control to consume it.

<?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:GraphicsHandler ="clr-namespace:Graphics"
x:Class="Graphics.MainPage">
    <ContentPage.Resources>
        <GraphicsHandler:GraphicsDrawable x:Key="gDrawable" />
    </ContentPage.Resources>
    <VerticalStackLayout>
        <GraphicsView Drawable="{StaticResource gDrawable}" HeightRequest="300" WidthRequest="400" />
    </VerticalStackLayout>
</ContentPage>
 

Drawing graphical object in GraphicsView canvas


Drawing a line

Draws a line from the start point (20, 20) to the end point (80, 80) of the line.

public void Draw(ICanvas canvas, RectF rectF)
{

canvas.StrokeColor = Colors.Blue;

canvas.StrokeSize = 3;

canvas.DrawLine(20, 20, 80, 80);

}

The result:

Drawing an ellipse

Draws an ellipse at (50, 50), width = 100, height = 50

public void Draw(ICanvas canvas, RectF rectF)
{
   canvas.StrokeColor = Colors.Blue;
   canvas.StrokeSize = 3;
   canvas.DrawEllipse(50, 50, 100, 50);
}

The result:

Drawing a rectangle

Rectangles and squares can be drawn at (40, 40) size 50x 80 as follow

public void Draw(ICanvas canvas, RectF rectF)
{

canvas.StrokeColor = Colors.DarkBlue;

canvas.FillColor = Colors.DarkBlue;

canvas.StrokeSize = 3;

canvas.DrawRectangle(40, 40, 50, 80);

}

The result:

Drawing an arc

Draw an arc at (20, 20), size 100x100, startAngle = 0, and endAngle = 270, clockwise = true and closed = false

public void Draw(ICanvas canvas, RectF rectF)
{

canvas.StrokeColor = Colors.Teal;

canvas.StrokeSize = 3;

canvas.DrawArc(20, 20, 100, 100, 0, 270, false, false);

}

The result:

Draw a FillArc at (20, 20), size 100x100, startAngle = 180, and endAngle = 360, closed = true

public void Draw(ICanvas canvas, RectF rectF)
{

canvas.FillColor = Colors.Teal;

canvas.FillArc(20, 20, 100, 100, 180, 360, true);

}

The result:

Drawing a path

A path is a collection of one or more contours that contain straight lines and/or curves. We can use the paths to draw curves and complex shapes on the ICanvas by the DrawPath method, which requires a PathF instance.

A contour begins when you call call to the PathF.MoveTo method, that a point at the beginning of the contour and an initial current point. Then we can call the following methods to continue the contour with a line or curve shape from current point:

  • LineTo: Adds a straight line to the path.
  • CurveTo: Adds a cubic Bezier spline.
  • QuadTo: Adds a quadratic Bezier spline.
  • AddArc: Adds an arc.

The following code example shows how to draw a path.

 

public void Draw(ICanvas canvas, RectF rectF)
{

PathF path = new PathF();

path.MoveTo(50, 50);

path.LineTo(100, 200);

path.LineTo(200, 100);

path.Close();

canvas.StrokeColor = Colors.Green;

canvas.StrokeSize = 3;

canvas.DrawPath(path);

}

The result:

Drawing a string

Draw String in a bounding box at (x, y), box size: with x height, horizontal alignment, vertical alignment options. Furthermore, the Font, FontColor, and FontSize properties is also specified

using Font = Microsoft.Maui.Graphics.Font;

public void Draw(ICanvas canvas, RectF rectF)
{

canvas.FontColor = Colors.Black;

canvas.FontSize = 14;

canvas.Font = Font.DefaultBold;

canvas.DrawString("This text is displayed using the bold system font.", 20, 140, 350, 100, HorizontalAlignment.Left, VerticalAlignment.Top);

canvas.Font = new Font("Arial");

canvas.FontColor = Colors.Black;

canvas.SetShadow(new SizeF(5, 6), 4, Colors.Gray);

canvas.DrawString("This text has a shadow.", 20, 200, 300, 100, HorizontalAlignment.Left, VerticalAlignment.Top);

canvas.Font = Font.Default;

canvas.DrawString("Text is left aligned.", 20, 20, 370, 90, HorizontalAlignment.Left, VerticalAlignment.Top);

canvas.DrawString("Text is centered.", 20, 60, 370, 90, HorizontalAlignment.Center, VerticalAlignment.Top);

canvas.DrawString("Text is right aligned.", 20, 100, 380, 90, HorizontalAlignment.Right, VerticalAlignment.Top);

}

The result:

 

Images

Images are represented by the IImage  interface.

Note that: There are two different IImage interfaces in NET MAUI:

  • Maui.IImage is the interface that abstracts the Image control.
  • Maui.Graphics.IImage is used for image display, manipulation, and persistence when displaying graphics in a GraphicsView. 

The image is retrieved from the assembly and loaded as a stream and is drawn at (10, 10) with its size:

using Microsoft.Maui.Graphics.Platform;
using IImage = Microsoft.Maui.Graphics.IImage;
using System.Reflection;
 
public void Draw(ICanvas canvas, RectF rectF)
{
IImage image;
Assembly assembly = GetType().GetTypeInfo().Assembly;
using (Stream stream = assembly.GetManifestResourceStream("Graphics.Resources.Images.image.png"))
{
image = PlatformImage.FromStream(stream);
}
if (image != null)
{
 
canvas.DrawImage(image, 10, 10, image.Width, image.Height);
}
}
 
The result

 

Transforms

Translate: to shift graphical objects from one location to another.

public void Draw(ICanvas canvas, RectF rectF)
{

canvas.Translate(50, 50);
canvas.StrokeColor = Colors.Teal;
canvas.StrokeSize = 3;
canvas.DrawArc(0, 0, 100, 100, 0, 180, false, false);
// Translate transform is used to shift the arc to (200, 200):
canvas.FillColor = Colors.Red;

}

In figure, the left are not translate before draw arc at (0, 0), the right is translate to (50, 50) before draw it.

Scale: to increase or decrease coordinates and size by (x, y).

  • If values x and y are between 0 and 1, the width and height of the scaled object decrease.
  • If values x and y are greater than 1, the width and height of the scaled object increase.
  • if values x, y of 1 indicate, the object is not scaled.

 

public void Draw(ICanvas canvas, RectF rectF)
{

canvas.StrokeColor = Colors.Red;

canvas.StrokeSize = 3;

canvas.StrokeDashPattern = new float[] { 2, 2 };

canvas.FontColor = Colors.Blue;

canvas.FontSize = 15;

canvas.DrawRoundedRectangle(60, 60, 80, 40, 5);

canvas.DrawString("ISB Vietnam", 60, 60, 80, 20, HorizontalAlignment.Left, VerticalAlignment.Top);

canvas.Scale(2, 2);

canvas.DrawRoundedRectangle(60, 100, 80, 40, 5);

canvas.DrawString("ISB Vietnam", 60, 100, 80, 20, HorizontalAlignment.Left, VerticalAlignment.Top);

}

The result:

Rotate: to rotate graphical objects around a point with an angle degree.

public void Draw(ICanvas canvas, RectF rectF)
{

canvas.FontColor = Colors.Black;
canvas.FontSize = 15;
// rotate 60 degrees
canvas.Rotate(60, rectF.Center.X, rectF.Center.Y);

canvas.DrawString("ISB Vietnam", rectF.Center.X, rectF.Center.Y, HorizontalAlignment.Left);

}

The result:

Summary

In this blog I show how to use GraphicsView canvas to draw graphical objects in .NET MAUI.

It is necessary to  create a class that derives from IDrawable interface and implement Draw method.

All graphical objects are drawn in this method by an ICanvas instance.

Reference

[1]. https://learn.microsoft.com/en-us/dotnet/maui/user-interface/graphics/?view=net-maui-8.0

[2]. https://www.syncfusion.com/blogs/post/draw-2d-graphics-in-dotnet-maui-graphicsview.aspx

[3]. https://www.youtube.com/playlist?list=PLdo4fOcmZ0oUBAdL2NwBpDs32zwGqb9DY.  James Montemagno

[4]. https://dotnet.microsoft.com/en-us/apps/maui

[5]. https://www.flaticon.com/free-icon/responsive-design_4661538

Leave a comment

*