【问题标题】:Retrieve image from SignaturePadView with MVVM architecture使用 MVVM 架构从 SignaturePadView 检索图像
【发布时间】:2018-02-07 21:14:35
【问题描述】:

我正在 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 对象始终为空。我认为问题在于小部件绑定,但我不确定。

【问题讨论】:

    标签: c# xamarin.forms prism signaturepad


    【解决方案1】:

    这是使用 SignaturePad 的另一种方式(这有助于避免将视图放入视图模型中)。我本可以使用事件聚合器系统将消息从 VM 发送到 View,但使用 Func 对我来说是最简单的解决方案。

    注意,我根本不使用 Prism,所以最终的解决方案可能会有点不同......

    签名视图的 XAML 部分在没有设置 BindingContext 的情况下几乎相同(来自我的文件 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" />
    

    在我的页面 (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
        });
    }
    

    【讨论】:

    • 感谢您的帮助。它也适用于 Prism。只是澄清一下:SignatureView.Points 是一个 IEnumerable 并且不支持 Count。
    • 你是对的,如果我包含 System.Linq,它可以正常工作而无需其他解决方法。谢谢大家!
    猜你喜欢
    • 2019-06-25
    • 1970-01-01
    • 1970-01-01
    • 2019-11-07
    • 2020-07-10
    • 1970-01-01
    • 2017-09-15
    • 1970-01-01
    • 2011-08-25
    相关资源
    最近更新 更多