[英]Retrieve image from SignaturePadView with MVVM architecture
我正在使用MVVM架構中的Prism框架開發Xamarin.Forms應用程序。 我需要從屏幕上收集簽名,所以我決定加入SignaturePad庫。 使用NuGet,我收錄了Xamarin.Controls.SignaturePad和Xamarin.Controls.SignaturePad.Forms包。 在頁面布局中(使用XAML構建)我有簽名小部件:
<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}" />
在ViewModel中,小部件綁定:
private SignaturePadView _sign;
public SignaturePadView Sign
{
get { return _sign; }
set { SetProperty(ref _sign, value); }
}
在ViewModel構造函數中:
_sign = new SignaturePadView();
還有一個按鈕,在這個按鈕的動作中我需要讀取符號圖像並將其保存到數據庫中。 我試過這個:
Stream sig = await Sign.GetImageStreamAsync(SignatureImageFormat.Png);
var signatureMemoryStream = sig as MemoryStream;
byte[] data = signatureMemoryStream.ToArray();
所有這些代碼都寫在便攜式項目中。 不幸的是它不起作用,因為sig對象總是為null。 我認為問題是小部件綁定但我不確定。
以下是使用SignaturePad的另一種方法(有助於避免在viewmodel中放置視圖)。 我本可以使用事件聚合器系統從VM向View發送消息,但使用Func對我來說是最簡單的解決方案。
請注意,我根本不使用Prism,所以最終的解決方案可能有點不同......
沒有BindingContext集(從我的文件TestPage.xaml),簽名視圖的XAML部分幾乎相同
<signature:SignaturePadView Margin="-10, 0, -10, 0"
x:Name="SignatureView"
HorizontalOptions="FillAndExpand"
VerticalOptions="FillAndExpand"
HeightRequest="150"
CaptionText="Signature"
CaptionTextColor="Blue"
ClearText="Effacer"
ClearTextColor="Black"
PromptText=""
PromptTextColor="Green"
BackgroundColor="Silver"
SignatureLineColor="Black"
StrokeWidth="3"
StrokeColor="Black" />
在我的頁面的代碼隱藏(TestPage.xaml.cs)
protected override void OnBindingContextChanged()
{
base.OnBindingContextChanged();
var vm = (TestViewModel)BindingContext; // Warning, the BindingContext View <-> ViewModel is already set
vm.SignatureFromStream = async () =>
{
if (SignatureView.Points.Count() > 0)
{
using (var stream = await SignatureView.GetImageStreamAsync(SignaturePad.Forms.SignatureImageFormat.Png))
{
return await ImageConverter.ReadFully(stream);
}
}
return await Task.Run(() => (byte[])null);
};
}
其中ImageConverter.ReadFully(...)只是一個到字節轉換器的流
public static class ImageConverter
{
public static async Task<byte[]> ReadFully(Stream input)
{
byte[] buffer = new byte[16 * 1024];
using (var ms = new MemoryStream())
{
int read;
while ((read = await input.ReadAsync(buffer, 0, buffer.Length)) > 0)
{
ms.Write(buffer, 0, read);
}
return ms.ToArray();
}
}
}
視圖模型看起來像這樣
public class TestViewModel : ViewModelBase
{
public Func<Task<byte[]>> SignatureFromStream { get; set; }
public byte[] Signature { get; set; }
public ICommand MyCommand => new Command(async () =>
{
Signature = await SignatureFromStream();
// Signature should be != null
});
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.