我尝试创建一个基于Xamarin表单的Image,它可以绑定一个字节数组。
我不想直接在我的ModelView中使用ImageSource,因为ModelViews也用于WPF UI。 所以我只想将字节数组(从base64字符串创建)转换为可以由UI绑定的图像。在WPF端没有问题,因为它可以采用bytearray格式的图像。现在我想为Xamarin Forms创建一个Custom-ImageControll,它可以接受/绑定一个字节数组并将其格式化为ImageSource。
此外,我不想为每个平台创建一个渲染器。我想使用Xamarin Image的标准渲染器。
如下所示,我创建了一个自定义图像(MVVMImage)并使用了Xamarin提供的基本图像。
问题是每次MVVMImage加载时我得到:System.Reflection.TargetInvocationException: <Timeout exceeded getting exception details>
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));
}
}
}
}
<?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; }
}
}
}
答案 0 :(得分:1)
一个问题是您处理可绑定属性更改的方式。
应该在属性更改而不是setter中处理。
它应该是这样的:
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));
}
}