Xamarin.Forms 在共享项目中设置图像源

Posted

技术标签:

【中文标题】Xamarin.Forms 在共享项目中设置图像源【英文标题】:Xamarin.Forms setting Image Source in shared project 【发布时间】:2021-04-21 20:38:26 【问题描述】:

我有一个适用于 androidios 项目的 Xamarin.Forms 解决方案。 我希望两个应用程序中都包含相同的图像。 我知道我可以将相同的图像分别添加到两个项目代码中,但这听起来不太优雅。 我希望共享项目中的代码中只有一个图像被两个项目引用。

我的图片在共享项目中,并且是Embedded Resource

SharedProject
|
- Resources
  |
  - icon192.png

我的 XAML(共享项目)

<ContentPage xmlns:myExtensions="clr-namespace:LibraryApp.Extensions;assembly=App">

    <Image x:Name="image2"
       VerticalOptions="Center" HeightRequest="50" Aspect="AspectFit"  />

    <Image Source="myExtensions:ImageResourceExtension Resources.icon192.png"
       VerticalOptions="Center" HeightRequest="50" Aspect="AspectFit"  />

</ContentPage>

我的代码隐藏(共享项目)

public partial class AboutPage : ContentPage

    public AboutPage()
    
        InitializeComponent();

        image2.Source = ImageSource.FromResource("LibraryApp.AndroidClient.Resources.icon192.png");
    

第一张图片,image2完美运行,当从代码隐藏设置时。 但我不想在代码隐藏中处理图像,因为它们是演示细节,而不是实现。

所以我尝试解决这个问题的扩展方法

namespace LibraryApp.Extensions

    [Preserve(AllMembers = true)]
    [ContentProperty(nameof(Source))]
    public class ImageResourceExtension : IMarkupExtension
    
        public string Source  get; set; 

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

            // do some work to get the name of the correct assembly/project, here
            // var stream = Assembly.GetCallingAssembly().GetManifestResourceStream(Source);

            // just for testing, return something we know that works
            return ImageSource.FromResource("LibraryApp.AndroidClient.Resources.icon192.png");
        
    

此扩展方法确实从另一张图片中调用(使用正确的Source 参数)。 即使代码实际上完全相同相同,我也无法使用扩展方法获取图像。

我收到了FileImageSourceHandler: Could not find image or image file was invalid

你会如何解决这个问题?

【问题讨论】:

【参考方案1】:

典型的,在这个问题上花了一天的时间后,我在问这个问题后发现了 20m...

一种解决方案是添加一个 IValueConverter

public class ResourceConverter : IValueConverter


    public Object Convert(Object value, Type targetType, Object parameter, System.Globalization.CultureInfo culture)
    
        if (value is not String filename) throw new ArgumentNullException(nameof(value));

        var nameOfAssembly = Assembly.GetExecutingAssembly().GetName().Name;
        return ImageSource.FromResource($"nameOfAssembly.filename");
    

    public Object ConvertBack(Object value, Type targetType, Object parameter, System.Globalization.CultureInfo culture)
    
        return null;
    

然后在 XAML 中

<ContentPage xmlns:converter="clr-namespace:GPS4Flight.Converter">
    <ContentPage.Resources>
        <converter:ResourceConverter x:Key="ResourceConverter" />
    </ContentPage.Resources>

    <Image Source="Binding Source=Resources.icon192.png, Converter=StaticResource ResourceConverter"
           VerticalOptions="Center" HeightRequest="50" Aspect="AspectFit"  />
</ContentPage>

请注意,我需要 Binding Source=[nameOfFile] 才能使用它。

【讨论】:

以上是关于Xamarin.Forms 在共享项目中设置图像源的主要内容,如果未能解决你的问题,请参考以下文章

如何在 iOS 的 xamarin.forms 应用程序中设置应用程序的应用程序图标

Xamarin Forms:获取存储在共享项目中的图像文件的路径?

在Xamarin Forms中设置TableView宽度和高度

Xamarin 表单集合视图 ItemsSource 绑定未更新 UI

如何在Xamarin Forms中设置自动日/夜模式谷歌地图

无法在 UWP 中设置 SQLite 对象 - Xamarin Forms