【问题标题】:Creating Xamarin Custom Image without device Renderer在没有设备渲染器的情况下创建 Xamarin 自定义图像
【发布时间】:2018-06-04 07:15:40
【问题描述】:

我正在尝试创建一个基于 Xamarin 表单图像的图像,该图像可以与字节数组绑定。

我不想直接在我的 ModelView 中使用 ImageSource,因为 ModelView 也用于 WPF UI。

所以我只想将字节数组(从 base64 字符串创建)转换为可以由 UI 绑定的图像。在 WPF 端没有问题,因为它可以获取 bytearray 格式的图像。现在我想为 Xamarin Forms 创建一个 Custom-ImageControll,它可以获取/绑定一个字节数组并将其格式化为 ImageSource。

我也不想为每个平台创建一个渲染器。我想使用 Xamarin Image 的标准渲染器。

如下所示,我创建了一个自定义图像(MVVMImage)并使用 Xamarin 提供的基本图像。

问题是每次加载 MVVMImage 时我都会得到:

System.Reflection.TargetInvocationException:

自定义图片:

    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using Xamarin.Forms;

   namespace Testape
   {
      public class MVVMImage : Image
      {

          public MVVMImage() : base()
          {
            //Attempt to avoid of create renderer on every device. 
          }

          public static readonly BindableProperty ArraySourceProperty =
          BindableProperty.Create(nameof(ArraySource), typeof(byte[]), typeof(MVVMImage), "");

          public byte[] ArraySource
          {
              set
              {
                  this.Source = ImageSource.FromStream(() => new   MemoryStream(value));
              }
          }
      }
  }

主页 XAML

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:Testape;assembly=Testape"
             x:Class="Testape.MainPage">

    <local:MVVMImage ArraySource="{Binding Img}"
           VerticalOptions="Center"
           HorizontalOptions="Center"/>
</ContentPage>

主页代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;

namespace Testape
{
    public partial class MainPage : ContentPage
    {
        public MainPage()
        {
            InitializeComponent();
            byte[] bt = Convert.FromBase64String("iVBORw0KGgoAAA< And so on >AAAAAElFTkSuQmCC");
            BindingContext = new ViewModelMainw(bt);
        }
    }
}

#模型视图

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;

namespace Testape
{
    public class ViewModelMainw
    {
        byte[] bffapt;
        public ViewModelMainw(byte[] bff)
        {
            bffapt = bff;
        }
        public byte[] Img
        {
            get { return bffapt; }
        }
    }
}

【问题讨论】:

    标签: c# wpf xaml xamarin xamarin.forms


    【解决方案1】:

    一个问题是您处理可绑定属性更改的方式。

    它应该在属性更改而不是设置器中处理。

    应该是这样的:

    public static readonly BindableProperty ArraySourceProperty =
        BindableProperty.Create(nameof(ArraySource), typeof(byte[]), typeof(MVVMImage), null,
        BindingMode.OneWay, null, OnArraySourcePropertyChanged);
    
    public byte[] ArraySource
    {
        get { return (byte[])GetValue(ArraySourceProperty); }
        set { SetValue(ArraySourceProperty, value); }
    }
    
    private static void OnArraySourcePropertyChanged(BindableObject bindable, object oldvalue, object newvalue)
    {
        var control = (MVVMImage) bindable;
        if (control != null)
        {
            control.Source = ImageSource.FromStream(() => new  MemoryStream((byte[])newvalue));
        }
    }
    

    【讨论】:

    • 非常感谢,我的装订不好。
    • 很高兴我能帮上忙
    猜你喜欢
    • 2021-02-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-09
    • 2019-01-14
    相关资源
    最近更新 更多