DrawingView

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>

使用 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
};

以下屏幕截图显示了 Android 上生成的 DrawingView:

Android 上 DrawingView 的屏幕截图

多线条用法

默认情况下,DrawingView 仅支持 1 个线条。 若要启用 MultiLine,请将 IsMultiLineModeEnabled 设置为 true。 确保将 ShouldClearOnFinish 设置为 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,
};

以下屏幕截图显示了 Android 上生成的 DrawingView:

Android 上具有多行的 DrawingView 的屏幕截图

绘制线条完成时处理事件

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 的触控交互。 可以通过在 iOS 上将 ShouldDelayContentTouches 属性设置为 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> IDrawingLine 集合目前位于 DrawingView
IsMultiLineModeEnabled bool 切换到多条线模式。 如果为 true,则可以在线条之间释放点击/单击时在 DrawingView 中绘制多个线条。 备注:启用 ClearOnFinish 时,释放点击/单击后将清除线条。 此外,每条线绘制后将触发 DrawingLineCompletedCommand
ShouldClearOnFinish bool 指示释放点击/单击并绘制线条后是否清除 DrawingView。 备注:启用 IsMultiLineModeEnabled 时,这可能会导致意外行为。
DrawingLineStartedCommand ICommand 每当在 DrawingView 中开始绘制线条时,就会调用此命令。
DrawingLineCancelledCommand ICommand 每当在 DrawingView 中取消绘制线条时,就会调用此命令。
DrawingLineCompletedCommand ICommand 每当在 DrawingView 上完成线条绘制时,都会调用此命令。 。 请注意,在解除点击或单击后,会触发此操作。 启用 MultiLineMode 后,会多次触发此命令。
PointDrawnCommand ICommand 每当在 DrawingView 上完成点绘制时,都会调用此命令。
OnDrawingLineStarted EventHandler<DrawingLineStartedEventArgs> 开始绘制线条时会发生 DrawingView 事件。
OnDrawingLineCancelled EventHandler<EventArgs> 取消绘制线条时会发生 DrawingView 事件。
OnDrawingLineCompleted EventHandler<DrawingLineCompletedEventArgs> 线条绘制完成时会发生 DrawingView 事件。
OnPointDrawn EventHandler<PointDrawnEventArgs> 点绘制完成时会发生 DrawingView 事件。
LineColor Color DrawingView 上绘制线条时默认使用的颜色。
LineWidth float DrawingView 上绘制线条时默认使用的宽度。

DrawingLine

DrawingLine 包含点列表,并允许单独配置每种线条样式。

属性

属性 类型​​ 说明 默认值
LineColor Color DrawingView 上绘制线条时使用的颜色。 Colors.Black
LineWidth float DrawingView 上绘制线条时使用的宽度。 5
ObservableCollection<PointF> 构成线条的 PointF 的集合。 new()
粒度 int 此线条的粒度。 最小值为 5。 值越高,线条越平滑,程序越慢。 5
ShouldSmoothPathWhenDrawn bool 启用或是禁用以指定在绘制此线条时是否进行平滑(消除锯齿)处理。 false

自定义 IDrawingLine

将默认 DrawingLine 替换为自定义实现的操作分两步:

  1. 创建实现 IDrawingLine 的自定义类:
    public class MyDrawingLine : IDrawingLine
    {
        public ObservableCollection<PointF> Points { get; } = new();
        ...
    }
    
  2. 创建实现 IDrawingLineAdapter 的自定义类。
    public class MyDrawingLineAdapter : IDrawingLineAdapter
    {
        public IDrawingLine(MauiDrawingLine mauiDrawingLine)
        {
            return new MyDrawingLine
            {
                Points = mauiDrawingLine.Points,
                ...
            }
        }
    }
    
  3. IDrawingViewHandler 中设置自定义 IDrawingLineAdapter
    var myDrawingLineAdapter = new MyDrawingLineAdapter();
    drawingViewHandler.SetDrawingLineAdapter(myDrawingLineAdapter);
    

DrawingLineStartedEventArgs

包含最后一个绘图点的事件参数。

属性

属性 类型​​ 描述
Point PointF 最后一个绘图点。

DrawingLineCompletedEventArgs

包含最后一个绘图线的事件参数。

属性

属性 类型​​ 描述
LastDrawingLine IDrawingLine 最后一个绘图线。

PointDrawnEventArgs

包含最后一个绘图点的事件参数。

属性

属性 类型​​ 描述
Point PointF 最后一个绘图点。

方法

方法 说明
GetImageStream 检索当前在 DrawingView 上绘制的包含 Lines 图像的 Stream
GetImageStream(静态) 检索当前作为参数提供的包含 IDrawingLine 图像集合的 Stream

示例

可以在 .NET MAUI 社区工具包示例应用程序中找到此功能的示例。

API

可以在 .NET MAUI 社区工具包 GitHub 存储库查看DrawingView 的源代码