DrawingView

DrawingView proporciona una superficie que permite el dibujo de líneas mediante el uso de la interacción táctil o del mouse. El resultado de un dibujo de usuarios se puede guardar como una imagen. Un caso de uso común para esto es proporcionar un cuadro de firma en una aplicación.

Uso básico

DrawingView permite establecer el color de línea, el ancho de línea y enlazar a la colección de líneas.

XAML

Incluir el espacio de nombres XAML

Para usar el kit de herramientas en XAML, es necesario agregar el siguiente xmlns a la página o vista:

xmlns:toolkit="http://schemas.microsoft.com/dotnet/2022/maui/toolkit"

Por lo tanto, lo siguiente:

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

Se modificaría para incluir el xmlns de la siguiente manera:

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

Uso de 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
};

La siguiente captura de pantalla muestra la DrawingView resultante en Android:

Captura de pantalla de drawingView en Android

Uso de MultiLine

De forma predeterminada DrawingView , solo admite 1 línea. Para habilitar MultiLine, establezca IsMultiLineModeEnabled en true. Asegúrese de que ShouldClearOnFinish es 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,
};

La siguiente captura de pantalla muestra la DrawingView resultante en Android:

Captura de pantalla de un drawingView con varias líneas en Android

Guardar el resultado en una imagen

El kit de herramientas de .NET MAUI Community ofrece varias opciones para guardar el dibujo resultante en una imagen, estas opciones son las siguientes:

Guardar desde DrawingView

DrawingView proporciona el método GetImageStream que generará una imagen y devolverá el contenido en un Stream.

En el ejemplo siguiente se exportará el dibujo a una imagen con un ancho deseado de 400 y un alto deseado de 300. Las dimensiones deseadas se ajustarán para garantizar que se mantenga la relación de aspecto del dibujo.

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

Note

De forma predeterminada, el GetImageStream método devolverá una imagen que contiene las líneas dibujadas, lo que no coincidirá con la superficie completa que ve el usuario. Para generar una imagen que coincida directamente con la superficie mostrada en la aplicación, se debe usar el GetImageStream método con el DrawingViewOutputOption parámetro .

En el ejemplo siguiente se muestra cómo generar una imagen que coincida directamente con la superficie DrawingView mostrada en una aplicación:

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

Guardar desde DrawingViewService

El uso de los métodos DrawingView puede dificultar la compilación de una aplicación mediante el patrón MVVM, para ayudar a tratar este .NET MAUI Community Toolkit también proporciona la clase DrawingViewService que también permitirá generar una secuencia de imágenes.

ImageLineOptions.JustLines

En el ejemplo siguiente se muestra cómo generar un flujo de imagen de un ancho deseado de 1920 y alto de 1080 y un fondo azul. Los desarrolladores pueden usar el ImageLineOptions.JustLines método para proporcionar opciones adecuadas para exportar solo las líneas dibujadas. Para exportar todo el lienzo, consulte ImageLineOptions.FullCanvas

await using var stream = await DrawingViewService.GetImageStream(
    ImageLineOptions.JustLines(Lines, new Size(1920, 1080), Brush.Blue));

ImageLineOptions.FullCanvas

Para generar una imagen que coincida directamente con la superficie DrawingView, se puede usar el ImageLineOptions.FullCanvas método como se indica a continuación.

await using var stream = await DrawingViewService.GetImageStream(
    ImageLineOptions.FullCanvas(Lines, new Size(1920, 1080), Brush.Blue, new Size(CanvasWidth, CanvasHeight)));

Para este ejemplo, las propiedades CanvasWidth y CanvasHeight se han enlazado mediante enlace de datos a las propiedades Width y Height de DrawingView, respectivamente. Para obtener la solución completa, consulte la aplicación de ejemplo .NET MAUI Community Toolkit.

Gestionar el evento cuando se completa la línea de dibujo

DrawingView permite suscribirse a los eventos como OnDrawingLineCompleted. El comando DrawingLineCompletedCommand correspondiente también está disponible.

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

Uso dentro de scrollView

Al usar el DrawingView dentro de un ScrollView, la interacción táctil con el ScrollView a veces puede verse interceptada en iOS. Esto se puede evitar estableciendo la propiedad ShouldDelayContentTouches en false en iOS, como se muestra en el siguiente ejemplo:

He resuelto este problema añadiendo ios:ScrollView.ShouldDelayContentTouches="false" al ScrollView que contiene el DrawingView:

<ContentPage
    xmlns:ios="clr-namespace:Microsoft.Maui.Controls.PlatformConfiguration.iOSSpecific;assembly=Microsoft.Maui.Controls">

    <ScrollView ios:ScrollView.ShouldDelayContentTouches="false">

        <DrawingView />

    </ScrollView>

</ContentPage>

Para obtener más información, consulte ScrollView content touches.

Uso avanzado

Para obtener todas las ventajas, DrawingView ofrece métodos para obtener el flujo de imágenes de las líneas dibujadas.

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

Propiedades

Propiedad Tipo Descripción
Líneas ObservableCollection<IDrawingLine> Colección de IDrawingLine que se encuentran actualmente en DrawingView
IsMultiLineModeEnabled bool Activa o desactiva el modo multilínea. Cuando es verdadero, se pueden dibujar varias líneas en el DrawingView aunque se suelte el toque o el clic entre una línea y otra. Nota: cuando ClearOnFinish también está habilitada, las líneas se borran después de que se libere la pulsación o el clic. Además, DrawingLineCompletedCommand se activará después de cada línea dibujada.
ShouldClearOnFinish bool Indica si DrawingView se borra al soltar la pulsación o el clic y dibujar una línea. Nota: cuando IsMultiLineModeEnabled también está habilitado, esto puede provocar un comportamiento inesperado.
ComandoDeInicioDeDibujoDeLínea ICommand Este comando se invoca cada vez que se inicia el dibujo de una línea en .DrawingView
DrawingLineCancelledCommand ICommand Este comando se invoca cada vez que se cancela el trazado de una línea en DrawingView.
DrawingLineCompletedCommand ICommand Este comando se invoca cada vez que se completa el dibujo de una línea en el DrawingView. . Tenga en cuenta que esto se activa después de soltar la pulsación o el clic. Cuando MultiLineMode está habilitado, este comando se desencadena varias veces.
PointDrawnCommand ICommand Este comando se invoca cada vez que se ha completado el dibujo de un punto en .DrawingView
OnDrawingLineStarted EventHandler<DrawingLineStartedEventArgs> DrawingView evento se produce cuando se empieza a dibujar una línea.
OnDrawingLineCancelled EventHandler<EventArgs> DrawingView se produce cuando se cancela la línea de dibujo.
OnDrawingLineCompleted EventHandler<DrawingLineCompletedEventArgs> DrawingView El evento se produce cuando se completa el trazado de la línea.
OnPointDrawn EventHandler<PointDrawnEventArgs> El evento DrawingView se produce cuando se dibuja un punto.
LineColor Color El color que se usa de forma predeterminada para dibujar una línea en DrawingView.
LineWidth float El ancho que se usa de forma predeterminada para dibujar una línea en el DrawingView.

DrawingLine

DrawingLine contiene la lista de puntos y permite configurar individualmente cada estilo de línea.

Propiedades

Propiedad Tipo Descripción Valor predeterminado
LineColor Color El color que se usa para dibujar la línea en el DrawingView. Colors.Black
Ancho de línea float El ancho que se usa para dibujar la línea en el DrawingView. 5
Puntos ObservableCollection<PointF> El conjunto de PointF que forma la línea. new()
Granularidad int Granularidad de esta línea. El valor mínimo es 5. Cuanto mayor sea el valor, más suave será la línea, más lenta será el programa. 5
Debería suavizar la ruta al dibujarse bool Activa o desactiva si se aplica suavizado de bordes a esta línea al dibujarla. false

IDrawingLine personalizado

Hay dos pasos para reemplazar el valor predeterminado DrawingLine por la implementación personalizada:

  1. Cree una clase personalizada que implemente IDrawingLine:
    public class MyDrawingLine : IDrawingLine
    {
        public ObservableCollection<PointF> Points { get; } = new();
        ...
    }
    
  2. Cree una clase personalizada que implemente IDrawingLineAdapter.
    public class MyDrawingLineAdapter : IDrawingLineAdapter
    {
        public IDrawingLine(MauiDrawingLine mauiDrawingLine)
        {
            return new MyDrawingLine
            {
                Points = mauiDrawingLine.Points,
                ...
            }
        }
    }
    
  3. Establecer IDrawingLineAdapter personalizado en IDrawingViewHandler:
    var myDrawingLineAdapter = new MyDrawingLineAdapter();
    drawingViewHandler.SetDrawingLineAdapter(myDrawingLineAdapter);
    

DrawingLineStartedEventArgs

Argumento de evento que contiene el último punto de dibujo.

Propiedades

Propiedad Tipo Descripción
Point PointF Último punto de dibujo.

DrawingLineCompletedEventArgs

Argumento de evento que contiene la última línea de dibujo.

Propiedades

Propiedad Tipo Descripción
LastDrawingLine IDrawingLine Última línea de dibujo.

PointDrawnEventArgs

Argumento de evento que contiene el último punto de dibujo.

Propiedades

Propiedad Tipo Descripción
Point PointF Último punto de dibujo.

Methods

Método Descripción
GetImageStream Recupera un objeto Stream que contiene una imagen de los Lines que se muestran actualmente en el DrawingView.
GetImageStream (estático) Recupera un Stream objeto que contiene una imagen de la colección de IDrawingLine que se proporciona como parámetro.

Ejemplos

Puede encontrar un ejemplo de esta característica en acción en la aplicación de ejemplo .NET MAUI Community Toolkit.

API

Puede encontrar el código fuente de DrawingView en el repositorio .NET MAUI Community Toolkit GitHub.