繪圖視圖

它 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 只支援一條線。 若要啟用 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 會回傳包含所繪線條的影像,這不會與使用者看到的完整表面相符。 為了產生與應用程式 GetImageStream 中顯示表面直接匹配的影像,必須使用帶有 DrawingViewOutputOption 參數的方法。

以下範例展示了如何產生與應用程式中 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 時,與 ScrollView 的觸控互動在 iOS 上有時可能會被攔截。 可依照以下範例,在 iOS 上將 ShouldDelayContentTouches 屬性設為 false,即可避免此情況。

我解決了這個問題,方法是在包含 DrawingView 的 ScrollView 中加入 ios:ScrollView.ShouldDelayContentTouches=“false” :

<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);

屬性

房產 類型 Description
行 ObservableCollection<IDrawingLine> 目前位於 DrawingView 上的 IDrawingLine 集合
IsMultiLineModeEnabled bool 切換多線模式。 若設為 true,則可在 DrawingView 上繪製多條線,並可在每條線之間放開輕觸/點擊。 注意:當 ClearOnFinish 也啟用時,在放開輕觸/點擊後,線條會被清除。 此外,每繪製一條線後,DrawingLineCompletedCommand 都會被觸發。
完成時應清除 bool 表示在放開輕觸/點按並畫出一條線後,是否會清除 DrawingView。 注意:當 IsMultiLineModeEnabled 也啟用時,可能會產生意外行為。
繪圖線條開始命令 ICommand 每當開始在 DrawingView 上繪製線條時,便會觸發此指令。
DrawingLineCancelledCommand ICommand 每當在 DrawingView 上畫線的操作被取消時,就會叫用此命令。
繪圖線完成指令 ICommand 當 在 上 DrawingView 繪製線條完成時,此指令會被呼叫。 . 請注意,此事件會在使用者放開輕觸或點擊後觸發。 當 MultiLineMode 啟用時,此指令會觸發多次。
PointDrawnCommand ICommand 每當在 DrawingView 上完成點的繪製時,此命令都會被呼叫。
開始繪製線條時 EventHandler<DrawingLineStartedEventArgs> DrawingView 事件發生在畫線開始時。
畫線取消 EventHandler<EventArgs> 當取消繪製線條時,會發生 DrawingView 事件。
線條繪製完成 EventHandler<DrawingLineCompletedEventArgs> DrawingView 事件會在線條繪製完成時發生。
OnPointDrawn EventHandler<PointDrawnEventArgs> DrawingView 事件發生於抽點時。
線條顏色 Color 預設用來在 DrawingView 上繪製線條的顏色。
線條寬度 float 預設用來在 DrawingView 上繪製線條的寬度。

畫線

包含 DrawingLine 點列表,並允許個別配置每種線條樣式。

屬性

房產 類型 Description 預設值
線條顏色 Color 用於在 DrawingView 上繪製線條的顏色。 Colors.Black
線條寬度 float 用於在 DrawingView 上繪製線條的寬度。 5
點數 ObservableCollection<PointF> 構成這條線的 PointF 集合。 new()
細粒度 int 此線條的粒度。 最小值是5。 值越高,線條越平滑,程式速度越慢。 5
繪製時應平滑路徑 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

包含最後一個繪圖點的事件引數。

屬性

房產 類型 Description
Point PointF 最後一個抽籤點。

繪製線條完成事件引數

包含最後繪圖線的事件參數。

屬性

房產 類型 Description
最後一條繪圖線 IDrawingLine 最後繪製的線條。

PointDrawnEventArgs

包含最後一個繪圖點的事件參數。

屬性

房產 類型 Description
Point PointF 最後一個抽籤點。

Methods

方法 Description
GetImageStream 擷取包含目前繪製於 DrawingView 上之 Lines 影像的 Stream。
GetImageStream(靜態) 擷取包含作為參數提供之 IDrawingLine 集合影像的 Stream。

Examples

您可以在 .NET MAUI 社群工具組範例應用程式中找到這項功能的範例。

API

你可以在 DrawingView找到 的原始碼。