I am not very familiar with Xamarin and I am not sure how to solve my current scenario, in a nutshell, I don't know how to call my method SaveSignature from outside the controller - below there is a bit of an explanation of the flow (I have stripped out some of the code for simplicity)
I have this controller SignaturePadController.xaml:
<?xml version="1.0" encoding="UTF-8"?>
<Frame
xmlns:signature="clr-namespace:SignaturePad.Forms;assembly=SignaturePad.Forms"
xmlns:lang="clr-namespace:Mobile.Business.Extensions;assembly=Mobile.Business"
x:Class="Mobile.UI.Controls.SignaturePadControl"
x:Name="this">
<StackLayout>
<signature:SignaturePadView
x:Name="SignaturePad"
x:FieldModifier="Public"/>
<controls:LabelEntryLayout x:Name="HiddenRecipientSignature" Value="{Binding RecipientSignature}" IsVisible="false"/>
</StackLayout>
</Frame>
SignaturePadController.xaml.cs:
namespace Mobile.UI.Controls
{
public partial class SignaturePadControl : Frame
{
public SignaturePadControl()
{
InitializeComponent();
}
public async void SaveSignature(object sender, EventArgs e)
{
var base64String = string.Empty;
using (var stream = AsyncHandler.RunSync(async () => await SignaturePad.GetImageStreamAsync(SignatureImageFormat.Png)))
{
if (stream == null) return;
var bytes = new byte[stream.Length];
stream.Read(bytes, 0, (int)stream.Length);
HiddenRecipientSignature.Value = Convert.ToBase64String(bytes);
}
}
}
}
Which I am using inside a view called BatchReviewPage like this:
<controls:SignaturePadControl
x:Name="SignaturePadControl"/>
The view model for the above view is called BatchReviewViewModel and it has the property that will contain the signature once saved:
private string _recipientSignature;
public string RecipientSignature
{
get => _recipientSignature;
set => SetAndRaiseIfChanged(ref _recipientSignature, value);
}
Now, I need to call the SaveSignature method from another view model called TargetViewModel - how do I do that?
This is the piece of code where I need to call the SaveSignature method:
var batchReviewVm = await ShowPopup<BatchReviewViewModel>();
if (batchReviewVm == null) return;
batchReviewVm.OnPopupClose = async () =>
{
switch (batchReviewVm.SelectedCloseOption)
{
case Batch.BatchViewModelBase<TrackerBatchItemModel>.CloseOption.Confirm:
//NEED TO CALL SaveSignature
break;
default:
break;
}
};
I'll explain a bit the code above.
I have a list of items, as soon as I click on one of them, I open the popup BatchReviewPage.xaml, I fill up the provided form and add a signature, as soon as Confirm is clicked I need to Save/Retrive the signature.
Thank you for your help
Comment replies: I do agree 100% with you @Jason, I know that is just wrong currently.
I have now created a bindable property on the SignaturePadControl, this is the library I am using https://github.com/xamarin/SignaturePad.
private static readonly Type _thisType = typeof(SignaturePadControl);
public static BindableProperty SignatureProperty =
BindableProperty.Create(
propertyName: nameof(Signature),
returnType: typeof(string),
declaringType: _thisType,
defaultValue: null,
defaultBindingMode: BindingMode.OneWay);
public string Signature
{
get => (string)GetValue(SignatureProperty);
set => SetValue(SignatureProperty, value);
}
This is how I use the controller:
<controls:SignaturePadControl
IsVisible="{Binding ShowRecipientSignaturePad}"
IsOkayVisible="True"
Signature="{Binding RecipientSignature}"/>
I am still very much struggling to understand how to trigger the save signature, I'd like to do it on the BatchReviewViewModel but can't figure out how to tell my code that it is time to save the signature.
I have tried to add properties to signature:SignaturePadView, like Focused, Unfocused, etc...to maybe trigger an event once the user has added the signature?! but that did nothing.
Thanks for you help
@Liqun Shen-MSFT, Yes it is and with that button inside the controller it works but it needs to be removed, that's why I am trying to trigger the save differently and in a different file.
In the end, I found a way to trigger the SaveSignature although it is not ideal.
I have managed to find 2 properties on the SignaturePadView to trigger when the User insert or clear a signature (StrokeCompleted and Cleared).
This is what my SignaturePadControl.xaml looks like:
And this is the code behind:
My BatchReviewViewModel stays the same:
This works for me, and I'll keep it as it is for now.
I have tried to use BindebleProperty as suggested, but I failed.
This is the BindableProperty I had created but I felt lost since I wasn't sure how to proceed:
Was I supposed to bind Signature to StrokeCompleted? Who knows.
Thank you for all the suggestions.