Storing SignaturePad Points in Database and rebuilding

Hi All,

I'm storing a signature (by serializing points) in a database and then attempting to recreate the signature... and it's not going to plan. A snippet of my code is below

Code Behind

            private async void SaveButton_Clicked(object sender, EventArgs e)
            {
            string points_string = JsonConvert.SerializeObject(PadView.Points.ToArray());

           // store to db, fetch

           Xamarin.Forms.Point[] points = JsonConvert.DeserializeObject<Xamarin.Forms.Point[]>(points_string);

           SignaturePadCanvasView sig = new SignaturePadCanvasView();

                sig.Points = pnts;

                // img is null at this point
                Stream img = await sig.GetImageStreamAsync(SignatureImageFormat.Png);


                // do something with the stream, in my case add to a padf
        }

XAML

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
            xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
            xmlns:local="clr-namespace:H1PaperlessApp"
            xmlns:forms="clr-namespace:SignaturePad.Forms;assembly=SignaturePad.Forms"
            x:Class="H1PaperlessApp.Views.Temppage"
            Padding="10">

    <StackLayout>

        <forms:SignaturePadView x:Name="PadView"
                            HeightRequest="350"
                            WidthRequest="240"
                            BackgroundColor="White"
                            StrokeColor="Black"
                            StrokeWidth="2"/>

        <Button Text="Save" FontSize="30" BackgroundColor="DodgerBlue" TextColor="White"
            Clicked="SaveButton_Clicked"/>
    </StackLayout>
</ContentPage>

My problem is that GetImageStreamAsync is returning null and I can't work out why. Any suggestions?

Posts

  • ShaunBauerShaunBauer USMember ✭✭

    Looking at this with fresh eyes and seem to have narrowed down the issue to a difference between a code generated SignaturePad and a XAML generated one. I edited my XAML to include a new SignaturePad element and the simply cloned the points from one to the other on button click. Works as expected.

    However, setting the points of a SignaturePad created via code results in a zero array length.

    XAML

    <?xml version="1.0" encoding="utf-8" ?>
    <ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
                xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                xmlns:local="clr-namespace:H1PaperlessApp"
                xmlns:forms="clr-namespace:SignaturePad.Forms;assembly=SignaturePad.Forms"
                x:Class="H1PaperlessApp.Views.Temppage"
                Padding="10">
    
        <StackLayout>
    
            <forms:SignaturePadView x:Name="PadView"
                                HeightRequest="150"
                                WidthRequest="240"
                                BackgroundColor="White"
                                StrokeColor="Black"
                                StrokeWidth="2"/>
    
            <forms:SignaturePadView x:Name="ClonePadView"
                                HeightRequest="150"
                                WidthRequest="240"
                                BackgroundColor="White"
                                StrokeColor="Black"
                                StrokeWidth="2"/>
    
            <Button Text="Save" FontSize="30" BackgroundColor="DodgerBlue" TextColor="White"
                Clicked="SaveButton_Clicked"/>
    
        </StackLayout>
    </ContentPage>
    

    Code Behind (Cloning from one XAML Generated element to another). In this case, the second Points is set correctly

            private async void SaveButton_Clicked(object sender, EventArgs e)
            {
                var pnts = PadView.Points.ToArray(); // pnts = {Xamarin.Forms.Point[294]}
    
                var originalPoints = JsonConvert.SerializeObject(pnts);
    
                Xamarin.Forms.Point[] points = JsonConvert.DeserializeObject<Xamarin.Forms.Point[]>(originalPoints);
    
                ClonePadView.Points = points; // ClonePadView.Points = {Xamarin.Forms.Point[294]}
    
                Stream img = await ClonePadView.GetImageStreamAsync(SignatureImageFormat.Png);   
        }
    

    Code Behind (Creating the target SignaturePadView via code. note that the second points has a count of 0)

            private async void SaveButton_Clicked(object sender, EventArgs e)
            {
                var pnts = PadView.Points.ToArray();  // pnts = {Xamarin.Forms.Point[294]}
    
                var originalPoints = JsonConvert.SerializeObject(pnts);
    
                Xamarin.Forms.Point[] points = JsonConvert.DeserializeObject<Xamarin.Forms.Point[]>(originalPoints);
    
                SignaturePadView CodeClonePadView = new SignaturePadView { };
    
                CodeClonePadView.Points = points;  // ClonePadView.Points = {Xamarin.Forms.Point[0]}
    
                Stream img = await CodeClonePadView.GetImageStreamAsync(SignatureImageFormat.Png);
        }
    

    So is there a step missing to set points via code? Or is it not possible to set the points of a signaturepad that is not displayed on screen? In my case, I am extracting from a database and saving to a PDF. If saving points is not possible, I will need to look at storing the image

  • ShaunBauerShaunBauer USMember ✭✭

    I ended up storing the image as a byte[]... but seems odd that I can't rebuild the signature without displaying it.

    @mattleibow you seem to be an expert at SignaturePad - is this expected behaviour or have I missed something?

  • kalkotekedarkalkotekedar USMember ✭✭
    edited February 2018

    @ShaunBauer storing and retrieving points as a string works for me. Thank You!

  • ShaunBauerShaunBauer USMember ✭✭

    Hi @kalkotekedar - Are you creating the SignaturePad via XAML or code?

  • kalkotekedarkalkotekedar USMember ✭✭

    @ShaunBauer I am creating vai XML

Sign In or Register to comment.