I'm developing a Xamarin.Forms application with Prism framework in a MVVM architecture. I need to collect the signature from the screen, so I decided to include the SignaturePad library. With NuGet I included Xamarin.Controls.SignaturePad and Xamarin.Controls.SignaturePad.Forms packages. In page layout (built with XAML) I have the signature widget:
<signature:SignaturePadView
x:Name="padView"
HeightRequest="130"
CaptionText="Sign"
CaptionTextColor="Black"
ClearText="Clean"
ClearTextColor="Black"
BackgroundColor="White"
SignatureLineColor="Black"
StrokeWidth="2"
StrokeColor="Black"
BindingContext="{Binding Sign, Mode=TwoWay}" />
In the ViewModel the widget binding:
private SignaturePadView _sign;
public SignaturePadView Sign
{
get { return _sign; }
set { SetProperty(ref _sign, value); }
}
In the ViewModel constructor:
_sign = new SignaturePadView();
There is also a button, in the action of this button I need to read the sign image and save it to the database. I tried this:
Stream sig = await Sign.GetImageStreamAsync(SignatureImageFormat.Png);
var signatureMemoryStream = sig as MemoryStream;
byte[] data = signatureMemoryStream.ToArray();
All this code is written in the portable project. Unfortunately it doesn't work because the sig object is always null. I think that the problem is the widget binding but I'm not sure.
Here is another way of working with the SignaturePad (which helps to avoid putting views in your viewmodel). I could have used a event aggregator system to send a message from VM to View but using a Func was a easiest solution for me.
Pay attention, I don't use Prism at all, so the final solution could be a bit different...
The XAML part of the signature view is almost the same without BindingContext set (from my file TestPage.xaml)
In the codebehind of my page (TestPage.xaml.cs)
Where ImageConverter.ReadFully(...) is just a stream to byte converter
And the viewmodel looks like this