DrawingView
The DrawingView
provides a surface that allows for the drawing of lines through the use of touch or mouse interaction. The result of a users drawing can be saved out as an image.
A common use case for this is to provide a signature box in an application.
Basic usage
DrawingView
allows to set line color, line width and bind to the collection of lines.
XAML
Including the XAML namespace
In order to use the toolkit in XAML the following xmlns
needs to be added into your page or view:
xmlns:toolkit="http://schemas.microsoft.com/dotnet/2022/maui/toolkit"
Therefore the following:
<ContentPage
x:Class="CommunityToolkit.Maui.Sample.Pages.MyPage"
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml">
</ContentPage>
Would be modified to include the xmlns
as follows:
<ContentPage
x:Class="CommunityToolkit.Maui.Sample.Pages.MyPage"
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:toolkit="http://schemas.microsoft.com/dotnet/2022/maui/toolkit">
</ContentPage>
Using the DrawingView
<toolkit:DrawingView
Lines="{Binding MyLines}"
LineColor="Red"
LineWidth="5" />
C#
using CommunityToolkit.Maui.Views;
var drawingView = new DrawingView
{
Lines = new ObservableCollection<IDrawingLine>(),
LineColor = Colors.Red,
LineWidth = 5
};
The following screenshot shows the resulting DrawingView on Android:
MultiLine usage
By default DrawingView
supports only 1 line. To enable MultiLine
set IsMultiLineModeEnabled
to true. Make sure ShouldClearOnFinish
is false.
XAML
<views:DrawingView
Lines="{Binding MyLines}"
IsMultiLineModeEnabled="true"
ShouldClearOnFinish="false" />
C#
using CommunityToolkit.Maui.Views;
var gestureImage = new Image();
var drawingView = new DrawingView
{
Lines = new ObservableCollection<IDrawingLine>(),
IsMultiLineModeEnabled = true,
ShouldClearOnFinish = false,
};
The following screenshot shows the resulting DrawingView on Android:
Handle event when Drawing Line Completed
DrawingView
allows to subscribe to the events like OnDrawingLineCompleted
. The corresponding command DrawingLineCompletedCommand
is also available.
XAML
<views:DrawingView
Lines="{Binding MyLines}"
DrawingLineCompletedCommand="{Binding DrawingLineCompletedCommand}"
OnDrawingLineCompleted="OnDrawingLineCompletedEvent" />
C#
using CommunityToolkit.Maui.Views;
var gestureImage = new Image();
var drawingView = new DrawingView
{
Lines = new ObservableCollection<IDrawingLine>(),
DrawingLineCompletedCommand = new Command<IDrawingLine>(async (line) =>
{
var cts = new CancellationTokenSource(TimeSpan.FromSeconds(5));
var stream = await line.GetImageStream(gestureImage.Width, gestureImage.Height, Colors.Gray.AsPaint(), cts.Token);
gestureImage.Source = ImageSource.FromStream(() => stream);
})
};
drawingView.OnDrawingLineCompleted += async (s, e) =>
{
var cts = new CancellationTokenSource(TimeSpan.FromSeconds(5));
var stream = await e.LastDrawingLine.GetImageStream(gestureImage.Width, gestureImage.Height, Colors.Gray.AsPaint(), cts.Token);
gestureImage.Source = ImageSource.FromStream(() => stream);
};
Use within a ScrollView
When using the DrawingView
inside a ScrollView
the touch interaction with the ScrollView
can sometimes be intercepted on iOS. This can be prevented by setting the ShouldDelayContentTouches
property to false
on iOS as per the following example:
I solved this problem, by addding the ios:ScrollView.ShouldDelayContentTouches="false" to the ScrollView that contains the DrawingView:
<ContentPage
xmlns:ios="clr-namespace:Microsoft.Maui.Controls.PlatformConfiguration.iOSSpecific;assembly=Microsoft.Maui.Controls">
<ScrollView ios:ScrollView.ShouldDelayContentTouches="false">
<DrawingView />
</ScrollView>
</ContentPage>
For more information please refer to ScrollView content touches.
Advanced usage
To get the full benefits, the DrawingView
provides the methods to get the image stream of the drawing lines.
XAML
<toolkit:DrawingView
x:Name="DrawingViewControl"
Lines="{Binding MyLines}"
IsMultiLineModeEnabled="true"
ShouldClearOnFinish="true"
DrawingLineCompletedCommand="{Binding DrawingLineCompletedCommand}"
OnDrawingLineCompleted="OnDrawingLineCompletedEvent"
LineColor="Red"
LineWidth="5"
HorizontalOptions="Fill"
VerticalOptions="Fill">
<toolkit:DrawingView.Background>
<LinearGradientBrush StartPoint="0,0"
EndPoint="0,1">
<GradientStop Color="Blue"
Offset="0"/>
<GradientStop Color="Yellow"
Offset="1"/>
</LinearGradientBrush>
</toolkit:DrawingView.Background>
</toolkit:DrawingView>
C#
using CommunityToolkit.Maui.Views;
var gestureImage = new Image();
var drawingView = new DrawingView
{
Lines = new ObservableCollection<IDrawingLine>(),
IsMultiLineModeEnabled = true,
ShouldClearOnFinish = false,
DrawingLineCompletedCommand = new Command<IDrawingLine>(async (line) =>
{
var cts = new CancellationTokenSource(TimeSpan.FromSeconds(5));
var stream = await line.GetImageStream(gestureImage.Width, gestureImage.Height, Colors.Gray.AsPaint(), cts.Token);
gestureImage.Source = ImageSource.FromStream(() => stream);
}),
LineColor = Colors.Red,
LineWidth = 5,
Background = Brush.Red
};
drawingView.OnDrawingLineCompleted += async (s, e) =>
{
var cts = new CancellationTokenSource(TimeSpan.FromSeconds(5));
var stream = await e.LastDrawingLine.GetImageStream(gestureImage.Width, gestureImage.Height, Colors.Gray.AsPaint(), cts.Token);
gestureImage.Source = ImageSource.FromStream(() => stream);
};
// get stream from lines collection
var cts = new CancellationTokenSource(TimeSpan.FromSeconds(5));
var lines = new List<IDrawingLine>();
var stream1 = await DrawingView.GetImageStream(
lines,
new Size(gestureImage.Width, gestureImage.Height),
Colors.Black.
cts.Token);
// get steam from the current DrawingView
var stream2 = await drawingView.GetImageStream(gestureImage.Width, gestureImage.Height, cts.Token);
Properties
Property | Type | Description |
---|---|---|
Lines | ObservableCollection<IDrawingLine> |
Collection of IDrawingLine that are currently on the DrawingView |
IsMultiLineModeEnabled | bool |
Toggles multi-line mode. When true, multiple lines can be drawn on the DrawingView while the tap/click is released in-between lines. Note: when ClearOnFinish is also enabled, the lines are cleared after the tap/click is released. Additionally, DrawingLineCompletedCommand will be fired after each line that is drawn. |
ShouldClearOnFinish | bool |
Indicates whether the DrawingView is cleared after releasing the tap/click and a line is drawn. Note: when IsMultiLineModeEnabled is also enabled, this might cause unexpected behavior. |
DrawingLineStartedCommand | ICommand |
This command is invoked whenever the drawing of a line on the DrawingView has started. |
DrawingLineCancelledCommand | ICommand |
This command is invoked whenever the drawing of a line on the DrawingView has cancelled. |
DrawingLineCompletedCommand | ICommand |
This command is invoked whenever the drawing of a line on the DrawingView has completed. . Note that this is fired after the tap or click is lifted. When MultiLineMode is enabled this command is fired multiple times. |
PointDrawnCommand | ICommand |
This command is invoked whenever the drawing of a point on the DrawingView has completed. |
OnDrawingLineStarted | EventHandler<DrawingLineStartedEventArgs> |
DrawingView event occurs when drawing line started. |
OnDrawingLineCancelled | EventHandler<EventArgs> |
DrawingView event occurs when drawing line cancelled. |
OnDrawingLineCompleted | EventHandler<DrawingLineCompletedEventArgs> |
DrawingView event occurs when drawing line completed. |
OnPointDrawn | EventHandler<PointDrawnEventArgs> |
DrawingView event occurs when point drawn. |
LineColor | Color |
The color that is used by default to draw a line on the DrawingView . |
LineWidth | float |
The width that is used by default to draw a line on the DrawingView . |
DrawingLine
The DrawingLine
contains the list of points and allows configuring each line style individually.
Properties
Property | Type | Description | Default value |
---|---|---|---|
LineColor | Color |
The color that is used to draw the line on the DrawingView . |
Colors.Black |
LineWidth | float |
The width that is used to draw the line on the DrawingView . |
5 |
Points | ObservableCollection<PointF> |
The collection of PointF that makes the line. |
new() |
Granularity | int |
The granularity of this line. Min value is 5. The higher the value, the smoother the line, the slower the program. | 5 |
ShouldSmoothPathWhenDrawn | bool |
Enables or disables if this line is smoothed (anti-aliased) when drawn. | false |
Custom IDrawingLine
There are 2 steps to replace the default DrawingLine
with the custom implementation:
- Create custom class which implements
IDrawingLine
:public class MyDrawingLine : IDrawingLine { public ObservableCollection<PointF> Points { get; } = new(); ... }
- Create custom class which implements
IDrawingLineAdapter
.public class MyDrawingLineAdapter : IDrawingLineAdapter { public IDrawingLine(MauiDrawingLine mauiDrawingLine) { return new MyDrawingLine { Points = mauiDrawingLine.Points, ... } } }
- Set custom
IDrawingLineAdapter
inIDrawingViewHandler
:var myDrawingLineAdapter = new MyDrawingLineAdapter(); drawingViewHandler.SetDrawingLineAdapter(myDrawingLineAdapter);
DrawingLineStartedEventArgs
Event argument which contains last drawing point.
Properties
Property | Type | Description |
---|---|---|
Point | PointF |
Last drawing point. |
DrawingLineCompletedEventArgs
Event argument which contains last drawing line.
Properties
Property | Type | Description |
---|---|---|
LastDrawingLine | IDrawingLine |
Last drawing line. |
PointDrawnEventArgs
Event argument which contains last drawing point.
Properties
Property | Type | Description |
---|---|---|
Point | PointF |
Last drawing point. |
Methods
Method | Description |
---|---|
GetImageStream | Retrieves a Stream containing an image of the Lines that are currently drawn on the DrawingView . |
GetImageStream (static) | Retrieves a Stream containing an image of the collection of IDrawingLine that is provided as a parameter. |
Examples
You can find an example of this feature in action in the .NET MAUI Community Toolkit Sample Application.
API
You can find the source code for DrawingView
over on the .NET MAUI Community Toolkit GitHub repository.
.NET MAUI Community Toolkit