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

我有一个适用于 Android 和 iOS 项目的 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

你会如何解决这个问题?

【问题讨论】:

    标签: image xamarin.forms code-behind imagesource markup-extensions


    【解决方案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] 才能使用它。

    【讨论】:

      猜你喜欢
      • 2018-02-18
      • 1970-01-01
      • 2015-05-04
      • 2017-07-07
      • 2018-09-14
      • 1970-01-01
      • 1970-01-01
      • 2016-06-21
      • 1970-01-01
      相关资源
      最近更新 更多