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 のスクリーンショット

MultiLine の使い方

既定では、 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 のスクリーンショット

結果を画像に保存する

.NET MAUI Community Toolkit には、結果の描画を画像に保存するためのいくつかのオプションが用意されています。これらのオプションは次のとおりです。

DrawingView から保存

DrawingViewは、イメージを生成し、GetImageStream内の内容を返すStream メソッドを提供します。

次の使用例は、必要な幅 400、高さ 300 のイメージに図面をエクスポートします。 図面の縦横比が維持されるように、目的の寸法が調整されます。

await drawingView.GetImageStream(desiredWidth: 400, desiredHeight: 300);

Note

既定では、 GetImageStream メソッドは描画された線を含むイメージを返します。これは、ユーザーに表示される完全なサーフェスと一致しません。 アプリケーションに表示されるサーフェスに直接一致するイメージを生成するには、GetImageStream パラメーターを持つ DrawingViewOutputOption メソッドを使用する必要があります。

次の例は、アプリケーションに表示される DrawingView サーフェスに直接一致するイメージを生成する方法を示しています。

await drawingView.GetImageStream(desiredWidth: 400, desiredHeight: 300, imageOutputOption: DrawingViewOutputOption.FullCanvas);

DrawingViewService からの保存

DrawingView メソッドを使用すると、MVVM パターンを使用してアプリケーションをビルドすることが困難になる可能性があります。これを処理するために、.NET MAUI Community Toolkit には、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プロパティはそれぞれ、WidthHeightプロパティとDrawingViewプロパティにバインドされたデータです。 完全なソリューションについては、.NET MAUI Community Toolkit サンプル アプリケーションを参照してください。

線の描画が完了したときにイベントを処理する

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 内で使用する

DrawingView内でScrollViewを使用すると、ScrollViewとのタッチ操作が iOS でインターセプトされることがあります。 これは、次の例に従って、 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);

プロパティ

財産 タイプ Description
明細行 ObservableCollection<IDrawingLine> 現在DrawingView上にあるIDrawingLineのコレクション
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 イベントは、線の描画が開始されたときに発生します。
線の描画がキャンセルされた EventHandler<EventArgs> DrawingView イベントは、描画線が取り消されたときに発生します。
OnDrawingLineCompleted EventHandler<DrawingLineCompletedEventArgs> DrawingView イベントは、線の描画が完了したときに発生します。
OnPointDrawn EventHandler<PointDrawnEventArgs> DrawingView イベントは、ポイントが描画されたときに発生します。
線の色 Color DrawingViewに線を描画するために既定で使用される色。
線幅 float DrawingViewに線を描画するために既定で使用される幅。

DrawingLine

DrawingLineにはポイントの一覧が含まれており、各線スタイルを個別に構成できます。

プロパティ

財産 タイプ Description 既定値
線の色 Color DrawingViewに線を描画するために使用される色。 Colors.Black
LineWidth float DrawingViewに線を描画するために使用する幅。 5
ポイント ObservableCollection<PointF> 行を構成するPointFの集まり。 new()
粒度 int この行の細分性。 最小値は 5 です。 値が大きいほど、線が滑らかくなり、プログラムが遅くなります。 5
描画時にパスを滑らかにするかどうか bool 描画時にこの線をスムージング (アンチエイリアス) する場合に有効または無効にします。 false

カスタム IDrawingLine

既定の DrawingLine をカスタム実装に置き換えるには、次の 2 つの手順があります。

  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. IDrawingLineAdapterでカスタム IDrawingViewHandlerを設定します。
    var myDrawingLineAdapter = new MyDrawingLineAdapter();
    drawingViewHandler.SetDrawingLineAdapter(myDrawingLineAdapter);
    

DrawingLineStartedEventArgs

最後の描画ポイントを含むイベント引数。

プロパティ

財産 タイプ Description
Point PointF 最後の描画ポイント。

DrawingLineCompletedEventArgs

最後の描画線を含むイベント引数。

プロパティ

財産 タイプ Description
最後の描画線 IDrawingLine 最後の描画線。

PointDrawnEventArgs

最後の描画ポイントを含むイベント引数。

プロパティ

財産 タイプ Description
Point PointF 最後の描画ポイント。

Methods

メソッド Description
GetImageStream 現在DrawingViewに描画されているLinesの画像を含むStreamを取得します。
GetImageStream (静的) パラメーターとして指定されたStreamのコレクションのイメージを含むIDrawingLineを取得します。

例示

この機能の例は、.NET MAUI Community Toolkit サンプル アプリケーションで動作しています。

API

DrawingView のソース コードは、.NET MAUI Community Toolkit GitHub リポジトリで確認できます。