DrawingView
提供了一个图面,允许使用触摸或鼠标交互绘制线条。 用户绘图的结果可以保存为图像。
一个常见的用例是在应用程序中提供签名框。
基本用法
DrawingView
允许设置线条颜色、线条宽度并绑定到线条集合。
XAML
包括 XAML 命名空间
若要在 XAML 中使用工具包,需要将以下 xmlns
添加到页面或视图中:
xmlns:toolkit="http://schemas.microsoft.com/dotnet/2022/maui/toolkit"
因此,请执行以下步骤:
<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>
将被修改为包含 xmlns
,具体如下:
<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>
使用绘图视图功能
<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
};
以下屏幕截图显示了 Android 上生成的 DrawingView:
Android 上 DrawingView 的屏幕截图
多行用法
默认情况下,DrawingView
仅支持 1 行。 若要启用 MultiLine
,请将 IsMultiLineModeEnabled
设置为 true。 请确保 ShouldClearOnFinish
为假。
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,
};
以下屏幕截图显示了 Android 上生成的 DrawingView:
在 Android 上支持多行的 DrawingView 屏幕截图
将结果保存为图像文件
.NET MAUI 社区工具包提供了几种用于将生成的绘图保存到图像的选项,这些选项如下所示:
从 DrawingView
保存
DrawingView
提供了 GetImageStream
方法,该方法将生成图像并返回 Stream
中的内容。
以下示例将绘图导出到所需宽度为 400 的图像,所需高度为 300。 将调整期望的尺寸,以确保保留绘图的纵横比。
await drawingView.GetImageStream(desiredWidth: 400, desiredHeight: 300);
注意
默认情况下,GetImageStream
方法将返回包含绘制线条的图像,这与用户看到的完整图面不匹配。 若要生成与应用程序中显示的图面直接匹配的图像,必须使用具有 DrawingViewOutputOption
参数的 GetImageStream
方法。
以下示例演示如何生成与应用程序中显示的 DrawingView 图面直接匹配的图像:
await drawingView.GetImageStream(desiredWidth: 400, desiredHeight: 300, imageOutputOption: DrawingViewOutputOption.FullCanvas);
从 DrawingViewService
保存
使用 DrawingView
方法可能会使使用 MVVM 模式生成应用程序变得困难,以帮助处理此 .NET MAUI 社区工具包还提供 DrawingViewService
类,该类还允许生成图像流。
ImageLineOptions.JustLines
下面的示例演示如何生成所需宽度为 1920 的图像流,高度为 1080 和蓝色背景。 开发人员可以使用 ImageLineOptions.JustLines
方法提供适当的选项来仅导出绘制的线条。 若要导出整个画布,请参阅 ImageLineOptions.FullCanvas
await using var stream = await DrawingViewService.GetImageStream(
ImageLineOptions.JustLines(Lines, new Size(1920, 1080), Brush.Blue));
ImageLineOptions.FullCanvas
为了生成与 DrawingView 图面直接匹配的图像,可以使用 ImageLineOptions.FullCanvas
方法,如下所示。
await using var stream = await DrawingViewService.GetImageStream(
ImageLineOptions.FullCanvas(Lines, new Size(1920, 1080), Brush.Blue, new Size(CanvasWidth, CanvasHeight)));
在此示例中,CanvasWidth
和 CanvasHeight
属性已分别绑定到 DrawingView
的 Width
和 Height
属性。 有关完整解决方案,请参阅 .NET MAUI 社区工具包示例应用程序。
绘制线条完成时处理事件
DrawingView
允许订阅 OnDrawingLineCompleted
等事件。 还可以使用相应的命令 DrawingLineCompletedCommand
。
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);
};
在 ScrollView 中使用
在 ScrollView
内使用 DrawingView
时,有时可以在 iOS 上截获与 ScrollView
的触摸交互。 可以通过将 ShouldDelayContentTouches
属性设置为在 iOS 上 false
来防止这种情况,如以下示例所示:
我解决了此问题,方法是将 ios:ScrollView.ShouldDelayContentTouches=“false”添加到包含 DrawingView 的 ScrollView:
<ContentPage
xmlns:ios="clr-namespace:Microsoft.Maui.Controls.PlatformConfiguration.iOSSpecific;assembly=Microsoft.Maui.Controls">
<ScrollView ios:ScrollView.ShouldDelayContentTouches="false">
<DrawingView />
</ScrollView>
</ContentPage>
有关详细信息,请参阅 ScrollView 内容涉及。
高级用法
为了获得全部优势,DrawingView
提供了获取绘图线图像流的方法。
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);
性能
财产 | 类型 | 描述 |
---|---|---|
线 | ObservableCollection<IDrawingLine> |
当前位于 DrawingView 上的 IDrawingLine 集合 |
是否启用多行模式 | bool |
切换多行模式。 如果为 true,则在两行之间释放点击/单击时,可以在 DrawingView 上绘制多个线条。 注意:当同时启用 ClearOnFinish 时,点击/单击释放后将清除这些行。 此外,绘制完每一行后,都会触发 DrawingLineCompletedCommand 。 |
应在完成时清除 | bool |
指示在释放点击/单击后是否清除 DrawingView 并绘制线条。 注意:启用 IsMultiLineModeEnabled 时,这可能会导致意外行为。 |
绘制线条开始命令 | ICommand |
每当开始在 DrawingView 上绘制线条时,就会调用此命令。 |
取消绘制线命令 | ICommand |
每当 DrawingView 上的线条绘图被取消时,就会调用此命令。 |
绘制线段完成命令 | ICommand |
每当 DrawingView 上的线条绘图完成时,就会调用此命令。 . 请注意,在解除点击或单击后,会触发此作。 启用 MultiLineMode 时,此命令将多次触发。 |
PointDrawnCommand | ICommand |
每当 DrawingView 上的点绘图完成时,就会调用此命令。 |
OnDrawingLineStarted | EventHandler<DrawingLineStartedEventArgs> |
DrawingView 事件在开始绘制线时发生。 |
绘制线取消时 | EventHandler<EventArgs> |
DrawingView 事件发生于绘制线条取消时。 |
完成绘制线 | EventHandler<DrawingLineCompletedEventArgs> |
绘制线条完成时发生 DrawingView 事件。 |
OnPointDrawn | EventHandler<PointDrawnEventArgs> |
绘制点时发生 DrawingView 事件。 |
线条颜色 | Color |
默认情况下用于在 DrawingView 上绘制线条的颜色。 |
线宽 | float |
默认情况下用于在 DrawingView 上绘制线条的宽度。 |
DrawingLine
DrawingLine
包含点列表,并允许单独配置每个线条样式。
性能
财产 | 类型 | 描述 | 默认值 |
---|---|---|---|
线条颜色 | Color |
用于在 DrawingView 上绘制线条的颜色。 |
Colors.Black |
线宽 | float |
用于在 DrawingView 上绘制线条的宽度。 |
5 |
分数 | ObservableCollection<PointF> |
构成线条的 PointF 的集合。 |
new() |
粒度 | int |
此行的粒度。 最小值为 5。 值越高,线条越平滑,程序执行越慢。 | 5 |
绘制时应平滑路径 | bool |
启用或禁用绘制此线条时的平滑(抗锯齿)功能。 | false |
自定义 IDrawingLine
有 2 个步骤可将默认 DrawingLine
替换为自定义实现:
- 创建实现
IDrawingLine
的自定义类:public class MyDrawingLine : IDrawingLine { public ObservableCollection<PointF> Points { get; } = new(); ... }
- 创建实现
IDrawingLineAdapter
的自定义类。public class MyDrawingLineAdapter : IDrawingLineAdapter { public IDrawingLine(MauiDrawingLine mauiDrawingLine) { return new MyDrawingLine { Points = mauiDrawingLine.Points, ... } } }
- 在
IDrawingViewHandler
中设置自定义IDrawingLineAdapter
:var myDrawingLineAdapter = new MyDrawingLineAdapter(); drawingViewHandler.SetDrawingLineAdapter(myDrawingLineAdapter);
绘图线开始事件参数
包含最后一个绘图点的事件参数。
性能
财产 | 类型 | 描述 |
---|---|---|
点 | PointF |
最后一个绘图点。 |
DrawingLineCompletedEventArgs
包含最后一个绘图线的事件参数。
性能
财产 | 类型 | 描述 |
---|---|---|
最后绘图线 | IDrawingLine |
最后一条绘图线条。 |
PointDrawnEventArgs
包含最后一个绘图点的事件参数。
性能
财产 | 类型 | 描述 |
---|---|---|
点 | PointF |
最后一个绘图点。 |
方法
方法 | 描述 |
---|---|
GetImageStream | 检索一个 Stream ,其中包含当前在 DrawingView 上绘制的 Lines 的图像。 |
GetImageStream (静态) | 检索一个 Stream ,其中包含作为参数提供的 IDrawingLine 集合的图像。 |
例子
可以在 .NET MAUI 社区工具包示例应用程序中找到此功能的示例。
应用程序接口
可以在 .NET MAUI 社区工具包 GitHub 存储库中找到 DrawingView
的源代码。