Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
O DrawingView fornece uma superfície que permite desenhar linhas por toque ou interação com o rato. O resultado do desenho de um utilizador pode ser guardado como imagem.
Um caso de uso comum para isto é fornecer uma caixa de assinatura numa aplicação.
Utilização básica
DrawingView permite definir a cor da linha, a largura da linha e a ligação à coleção de linhas.
XAML
Incluindo o namespace XAML
Para usar o kit de ferramentas em XAML, a seguinte xmlns precisa ser adicionada à sua página ou vista.
xmlns:toolkit="http://schemas.microsoft.com/dotnet/2022/maui/toolkit"
Por conseguinte, o seguinte:
<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>
Seria modificado para incluir o xmlns da seguinte forma:
<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>
Utilizar a vista de desenho
<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
};
A captura de ecrã seguinte mostra o resultado do DrawingView no Android:
Utilização de MultiLine
Por defeito DrawingView , suporta apenas 1 linha. Para ativar MultiLine definir IsMultiLineModeEnabled como verdadeiro. Certifique-se de que ShouldClearOnFinish está definido como falso.
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,
};
A captura de ecrã seguinte mostra o resultado do DrawingView no Android:
Guardar o resultado numa imagem
O .NET MAUI Community Toolkit oferece várias opções para guardar o desenho resultante numa imagem, sendo estas as seguintes:
Guardar a partir de DrawingView
O DrawingView fornece o método GetImageStream, que gera uma imagem e devolve o conteúdo num Stream.
O exemplo seguinte exportará o desenho para uma imagem com uma largura desejada de 400 e uma altura desejada de 300. As dimensões pretendidas serão ajustadas para garantir que a proporção de aspeto do desenho seja mantida.
await drawingView.GetImageStream(desiredWidth: 400, desiredHeight: 300);
Observação
Por defeito, o GetImageStream método devolverá uma imagem que contém as linhas desenhadas, mas esta não corresponderá à superfície completa que o utilizador vê. Para gerar uma imagem que corresponda diretamente à superfície apresentada na aplicação, é necessário utilizar o método GetImageStream com o parâmetro DrawingViewOutputOption.
O exemplo seguinte mostra como gerar uma imagem que corresponda diretamente à superfície DrawingView apresentada numa aplicação:
await drawingView.GetImageStream(desiredWidth: 400, desiredHeight: 300, imageOutputOption: DrawingViewOutputOption.FullCanvas);
A guardar a partir de DrawingViewService
A utilização dos métodos DrawingView pode dificultar a construção de uma aplicação usando o padrão MVVM; para ajudar a lidar com isso, o .NET MAUI Community Toolkit também disponibiliza a classe DrawingViewService que permite gerar um fluxo de imagens.
ImageLineOptions.JustLines
O exemplo seguinte mostra como gerar um fluxo de imagem com largura desejada de 1920, altura de 1080 e fundo azul. Os programadores podem usar o ImageLineOptions.JustLines método para fornecer opções adequadas para exportar apenas as linhas desenhadas. Para exportar toda a tela, veja ImageLineOptions.FullCanvas
await using var stream = await DrawingViewService.GetImageStream(
ImageLineOptions.JustLines(Lines, new Size(1920, 1080), Brush.Blue));
ImageLineOptions.FullCanvas
Para gerar uma imagem que corresponda diretamente à superfície do DrawingView, o ImageLineOptions.FullCanvas método pode ser usado da seguinte forma.
await using var stream = await DrawingViewService.GetImageStream(
ImageLineOptions.FullCanvas(Lines, new Size(1920, 1080), Brush.Blue, new Size(CanvasWidth, CanvasHeight)));
Para efeitos deste exemplo, as propriedades CanvasWidth e CanvasHeight foram associadas por enlace de dados às propriedades Width e Height do DrawingView, respetivamente. Para a solução completa, consulte o .NET MAUI Community Toolkit Sample Application.
Lidar com o evento quando a linha de desenho está concluída
DrawingView permite subscrever eventos como OnDrawingLineCompleted. O comando DrawingLineCompletedCommand correspondente também está disponível.
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);
};
Utilização dentro de um ScrollView
Ao utilizar o DrawingView dentro de um ScrollView, a interação por toque com o ScrollView pode, por vezes, ser intercetada no iOS. Isto pode ser evitado definindo a ShouldDelayContentTouches propriedade como false no iOS, conforme o seguinte exemplo:
Resolvi este problema adicionando o ios:ScrollView.ShouldDelayContentTouches="false" ao ScrollView que contém o DrawingView:
<ContentPage
xmlns:ios="clr-namespace:Microsoft.Maui.Controls.PlatformConfiguration.iOSSpecific;assembly=Microsoft.Maui.Controls">
<ScrollView ios:ScrollView.ShouldDelayContentTouches="false">
<DrawingView />
</ScrollView>
</ContentPage>
Para mais informações, consulte os detalhes do conteúdo do ScrollView.
Utilização avançada
Para obter todos os benefícios, o DrawingView disponibiliza os métodos para obter o fluxo de imagens das linhas de desenho.
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);
Propriedades
| Propriedade | Tipo | Descrição |
|---|---|---|
| Linhas | ObservableCollection<IDrawingLine> |
A coleção desses IDrawingLine encontra-se atualmente no DrawingView |
| IsMultiLineModeEnabled | bool |
Ativa ou desativa o modo multilinha. Quando ativado, podem ser desenhadas várias linhas no DrawingView se o toque/clique for libertado entre cada linha. Nota: quando ClearOnFinish também está ativado, as linhas são limpas após o toque ou clique ser libertado. Além disso, DrawingLineCompletedCommand será acionado após cada linha desenhada. |
| ShouldClearOnFinish | bool |
Indica se o DrawingView é apagado após libertar o toque/clique e é desenhada uma linha. Nota: quando IsMultiLineModeEnabled também está ativado, isto pode causar comportamentos inesperados. |
| ComandoInícioDoDesenhoDeLinha | ICommand |
Este comando é invocado sempre que o desenho de uma linha no DrawingView tem começado. |
| ComandoCanceladoDeDesenhoDeLinha | ICommand |
Este comando é invocado sempre que o desenho de uma linha no DrawingView é cancelado. |
| DesenhoLinhaCompletadaComando | ICommand |
Este comando é invocado sempre que o desenho de uma linha no DrawingView estiver concluído. . Tenha em atenção que isto é acionado depois de o toque ou clique ser libertado. Quando MultiLineMode está ativado, este comando é executado várias vezes. |
| ComandoPontoDesenhado | ICommand |
Este comando é invocado sempre que o desenho de um ponto em o DrawingView foi concluído. |
| AoIniciarLinhaDeDesenho | EventHandler<DrawingLineStartedEventArgs> |
DrawingView O evento ocorre quando se inicia o desenho da linha. |
| OnDrawingLineCancelled | EventHandler<EventArgs> |
DrawingView O evento ocorre quando o desenho de uma linha é cancelado. |
| OnDrawingLineConcluído | EventHandler<DrawingLineCompletedEventArgs> |
DrawingView o evento ocorre quando o desenho de linha estiver concluído. |
| OnPointDrawn | EventHandler<PointDrawnEventArgs> |
DrawingView o evento ocorre quando o ponto é desenhado. |
| LineColor | Color |
A cor que é utilizada por predefinição para traçar uma linha no DrawingView. |
| Largura da linha | float |
A largura utilizada por defeito para traçar uma linha no DrawingView. |
Linha de desenho
O DrawingLine contém a lista de pontos e permite configurar o estilo de cada linha individualmente.
Propriedades
| Propriedade | Tipo | Descrição | Valor padrão |
|---|---|---|---|
| LineColor | Color |
A cor usada para traçar a linha no DrawingView. |
Colors.Black |
| Largura de Linha | float |
A largura que é usada para desenhar a linha no DrawingView. |
5 |
| Pontos | ObservableCollection<PointF> |
A coleção de PointF que constitui a linha. |
new() |
| Granularidade | int |
A granularidade desta linha. Valor mínimo é 5. Quanto maior o valor, mais suave a linha, mais lento é o programa. | 5 |
| DeveriaSuavizarTrajetoAoDesenhar | bool |
Ativa ou desativa se esta linha for suavizada (anti-alias) quando desenhada. | false |
IDrawingLine Personalizada
Existem 2 passos para substituir o padrão DrawingLine pela implementação personalizada:
- Crie uma classe personalizada que implemente
IDrawingLine:public class MyDrawingLine : IDrawingLine { public ObservableCollection<PointF> Points { get; } = new(); ... } - Crie uma classe personalizada que implemente
IDrawingLineAdapter.public class MyDrawingLineAdapter : IDrawingLineAdapter { public IDrawingLine(MauiDrawingLine mauiDrawingLine) { return new MyDrawingLine { Points = mauiDrawingLine.Points, ... } } } - Definir
IDrawingLineAdapterpersonalizado emIDrawingViewHandler:var myDrawingLineAdapter = new MyDrawingLineAdapter(); drawingViewHandler.SetDrawingLineAdapter(myDrawingLineAdapter);
DrawingLineStartedEventArgs
Argumento de evento que contém o último ponto de desenho.
Propriedades
| Propriedade | Tipo | Descrição |
|---|---|---|
| Point | PointF |
Último ponto de desenho. |
Argumentos do Evento de Conclusão do Desenho de Linha
Argumento de evento que contém a última linha de desenho.
Propriedades
| Propriedade | Tipo | Descrição |
|---|---|---|
| LastDrawingLine | IDrawingLine |
Última linha de desenho. |
PointDrawnEventArgs
Argumento de evento que contém o último ponto de desenho.
Propriedades
| Propriedade | Tipo | Descrição |
|---|---|---|
| Point | PointF |
Último ponto de desenho. |
Methods
| Método | Descrição |
|---|---|
| GetImageStream | Obtém um Stream contendo uma imagem dos Lines que estão atualmente apresentados no DrawingView. |
| GetImageStream (estática) | Recupera uma Stream que contém uma imagem da coleção de IDrawingLine que é fornecida como parâmetro. |
Exemplos
Você pode encontrar um exemplo desse recurso em ação no .NET MAUI Community Toolkit Sample Application.
API
Você pode encontrar o código-fonte para DrawingView no repositório GitHub do .NET MAUI Community Toolkit.
.NET MAUI Community Toolkit