2017-08-30 2 views
1

Ich entwickle eine Xamarin.Forms-Anwendung mit Prism-Framework in einer MVVM-Architektur. Ich muss die Unterschrift vom Bildschirm abholen, also habe ich beschlossen, die SignaturePad-Bibliothek aufzunehmen. Mit NuGet habe ich Xamarin.Controls.SignaturePad und Xamarin.Controls.SignaturePad.Forms Pakete hinzugefügt. In Seitenlayout (mit XAML gebaut) Ich habe die Unterschrift Widget haben:Abbild von SignaturePadView mit MVVM-Architektur abrufen

<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}" /> 

Im Viewmodel das Widget-Bindung:

private SignaturePadView _sign; 
public SignaturePadView Sign 
{ 
    get { return _sign; } 
    set { SetProperty(ref _sign, value); } 
} 

Im Ansichtsmodell Konstruktor:

_sign = new SignaturePadView(); 

Es gibt Auch eine Schaltfläche, in der Aktion dieser Schaltfläche muss ich das Zeichen Bild lesen und in der Datenbank speichern. Ich versuchte dieses:

Stream sig = await Sign.GetImageStreamAsync(SignatureImageFormat.Png); 
var signatureMemoryStream = sig as MemoryStream; 
byte[] data = signatureMemoryStream.ToArray();    

All dieser Code wird im beweglichen Projekt geschrieben. Leider funktioniert es nicht, weil das sig-Objekt immer null ist. Ich denke, dass das Problem die Widgetbindung ist, aber ich bin mir nicht sicher.

Antwort

1

Hier ist eine andere Art der Arbeit mit dem SignaturePad (das hilft, Ansichten in Ihrem Ansichtsmodell zu vermeiden). Ich hätte ein Event-Aggregator-System verwenden können, um eine Nachricht von VM zu View zu senden, aber die Verwendung eines Func war eine einfache Lösung für mich.

beachten, ich Prism gar nicht verwenden, so dass die endgültige Lösung ein bisschen anders sein könnte ...

Der XAML Teil der Signatur Ansicht ohne Binding Satz fast das gleiche ist (aus meiner Datei TestPage.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" /> 

im Code-Behind meiner Seite (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); 
     }; 
    } 

Wo ImageConverter.ReadFully (...) ist nur ein Stream-Byte-Wandler

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(); 
     } 
    } 
} 

Und das Ansichtsmodell sieht wie folgt aus

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 
    }); 
} 
+1

Vielen Dank für Ihre Hilfe. Es funktioniert auch perfekt mit Prisma. Nur eine Klarstellung: SignatureView.Points ist ein IEnumerable und unterstützt den Count nicht. – TeoVr81

+0

@ TeoVr81 wenn ich mich erinnere, funktioniert Graf dank Linq – hugoterelle

+0

Sie haben Recht, wenn ich System.Linq einschließen funktioniert es ohne andere Umgehungslösungen. Danke für alles! – TeoVr81

Verwandte Themen