3

如你们所知,没有内置的类型转换器类可以将字符串转换为 ImageSource 对象。

当我想让我的模型有一个字符串属性表示嵌入图像的 ResouceID,然后 XAML 的 Image.Source 属性通过数据绑定绑定到该属性时,这给我带来了挑战。

最简单的解决方案是在模型中添加另一个 ImageSource 类型的属性,该属性仅获取基于字符串 ResourceID 属性生成的图像源对象,然后将其绑定到 Image.Source。

它运行良好,但问题是我必须将 Xamarin.Forms 依赖项添加到定义模型的项目中,该模型是 .NET Stardard 类库。

我按项目拆分视图和模型/视图模型,以便模型可以在其他应用程序中重用。因此,该模型被设计为只有基本类型,如 int、string 等。最简单的解决方案使模型类依赖于 Xamarin.Forms,我担心以后在用于其他框架时它是否会带来一些问题。

为了制定解决方案,我尝试通过引用MS文档在共享项目中声明具有绑定能力的标记扩展类,但不起作用。

扩展类代码如下。


// This class is added to the shared project, where a page class exsists.
public class BindableImageSourceExtension : BindableObject, IMarkupExtension
{
    // This is a unique property of BindableImageSource element
    public string ResourceID
    {
        get { return (string)GetValue(ResouceIDProperty); }
        set { SetValue(ResouceIDProperty, value); }
    }

    public object ProvideValue(IServiceProvider serviceProvider)
    {
        if(ResourceID == null) return null;

        // Images are embeded to a project named BusinessSession that holds Data class.
        return ImageSource.FromResource(ResourceID, typeof(BusinessSession).GetTypeInfo().Assembly); 
    }

    public static readonly BindableProperty ResouceIDProperty =
            BindableProperty.Create("ResourceID", typeof(string),
                                    typeof(BindableImageSourceExtension),
                                    default(string));
}

任何人都可以帮助解决这个问题?

4

1 回答 1

3

无需创建,解决方案在文档bindableproperty中列出:

因为没有从字符串到 ResourceImageSource 的内置类型转换器,所以这些类型的图像不能由 XAML 本机加载。相反,可以编写一个简单的自定义 XAML 标记扩展来使用 XAML 中指定的资源 ID 加载图像:

[ContentProperty (nameof(Source))]
public class ImageResourceExtension : IMarkupExtension
{
 public string Source { get; set; }

 public object ProvideValue (IServiceProvider serviceProvider)
 {
   if (Source == null)
   {
     return null;
   }

   // Do your translation lookup here, using whatever method you require
   var imageSource = ImageSource.FromResource(Source, typeof(ImageResourceExtension).GetTypeInfo().Assembly);

   return imageSource;
 }
}

在 Xaml 中:

 <StackLayout VerticalOptions="Center" HorizontalOptions="Center">
   <!-- use a custom Markup Extension -->
   <Image Source="{local:ImageResource WorkingWithImages.beach.jpg}" />
 </StackLayout>

您也可以创建自己的ValueConverter

public class stringToImageSourceConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return ImageSource.FromResource(value as string, typeof(MainPage).GetTypeInfo().Assembly);
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return value;
    }
}

在 Xaml 中:

<Image Source="{Binding Path, Converter={StaticResource stringToImage}}" VerticalOptions="CenterAndExpand" HorizontalOptions="CenterAndExpand" />

我在这里上传了一个示例项目。

于 2020-06-23T07:06:13.907 回答