它 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:
多線路的使用
預設 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:
的螢幕截圖
將結果儲存成影像
.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 替換成自訂實作:
- 建立自訂類別來實作
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);
DrawingLineStartedEventArgs
包含最後一個繪圖點的事件引數。
屬性
| 房產 | 類型 | Description |
|---|---|---|
| Point | PointF |
最後一個抽籤點。 |
繪製線條完成事件引數
包含最後繪圖線的事件參數。
屬性
| 房產 | 類型 | Description |
|---|---|---|
| 最後一條繪圖線 | IDrawingLine |
最後繪製的線條。 |
PointDrawnEventArgs
包含最後一個繪圖點的事件參數。
屬性
| 房產 | 類型 | Description |
|---|---|---|
| Point | PointF |
最後一個抽籤點。 |
Methods
| 方法 | Description |
|---|---|
| GetImageStream | 擷取包含目前繪製於 DrawingView 上之 Lines 影像的 Stream。 |
| GetImageStream(靜態) | 擷取包含作為參數提供之 IDrawingLine 集合影像的 Stream。 |
Examples
您可以在 .NET MAUI 社群工具組範例應用程式中找到這項功能的範例。