Search code examples
.netmauimaui-community-toolkit

How to convert a byte array to ObservableCollection of IDrawingLine for DrawingView Lines?


I have a Community Toolkit DrawingView in a .Net Maui ContentPage for capturing signatures. The DrawingView Lines property is bound to an ObservableCollection in the ViewModel.

XAML from ContentPage

<toolkit:DrawingView
    x:Name="DrawViewSignature"
    BackgroundColor="AliceBlue"
    HeightRequest="200"
    HorizontalOptions="FillAndExpand"
    IsEnabled="True"
    IsMultiLineModeEnabled="True"
    LineColor="Black"
    LineWidth="5"
    Lines="{Binding SignatureLines}"
    VerticalOptions="FillAndExpand"
    WidthRequest="340" />

I am able to capture the signature and get the byte array data from the DrawingView by converting it's bound ObservableCollection of IDrawingLine in the ViewModel.

C# From ViewModel. It inherits from ObservableValidator

[ObservableProperty]
private ObservableCollection<IDrawingLine> signatureLines = new();

DrawingView sigView = new DrawingView
{
    Lines = SignatureLines,
    IsMultiLineModeEnabled = true,
    ShouldClearOnFinish = false,
    LineColor = Colors.Black,
    LineWidth = 5,
    BackgroundColor = Colors.White,
    WidthRequest = 250,
    HeightRequest = 250
};
var stream1 = await sigView.GetImageStream(250, 250);
byte[] sigBytes = new byte[stream1.Length];
stream1.Read(sigBytes, 0, sigBytes.Length);

After this block of code, sigBytes contains the byte array of the lines drawn on the DrawingView. This all works OK. I can send the byte array to the server and save it in a DB or write it as an image file to disk.

I am having trouble setting the value of the ObservableCollection SignatureLines from a byte array when I need to display/load the saved signature into the DrawingView by setting SignatureLines.

How do I convert a byte array to a ObservableCollection of IDrawingLine?

I've checked documentation https://learn.microsoft.com/en-us/dotnet/communitytoolkit/maui/views/drawingview and https://github.com/jfversluis/MauiDrawingViewSample/blob/main/MainPage.xaml.cs

There are only examples of getting the byte array from the DrawingView, not setting it.


Solution

  • I'm afraid this is not possible to restore ObservableCollection from ImageStream byte array, because this is Image representation not the Collection of lines.

    But you can serialize ObservableCollection into JSON and then Deserialize it back like this:

    public ObservableCollection<IDrawingLine> Lines { get; set; } = [];
    
    public ObservableCollection<IDrawingLine> RestoredLines { get; set; } = [];
    
    private void TransferWithJson()
    {
        string jsonData = JsonSerializer.Serialize(Lines);
    
        // Save jsonData to database
    
        ObservableCollection<DrawingLine>? deserializedLines = JsonSerializer.Deserialize<ObservableCollection<DrawingLine>?>(jsonData);
        if (deserializedLines != null)
        {
            RestoredLines.Clear();
            foreach (DrawingLine line in deserializedLines)
            {
                RestoredLines.Add(line);
            }
        }
    }