如何从XAML中引用嵌入式资源?

32

我有几张图片想要嵌入到exe文件中。

当我将Build Action设置为Embedded Resource时,代码中出现了一个错误,提示资源不可用,并要求我将Build Action设置为Resource

我尝试了几种不同的方法:

 <ImageSource x:Key="Image_Background">YearBook;component/Resources/Images/darkaurora.png</ImageSource>

 <ImageSource x:Key="Image_Background">Images/darkaurora.png</ImageSource>

 <ImageSource x:Key="Image_Background">pack://application:,,,/Resources/Images/darkaurora.png</ImageSource>

这段代码位于资源文件中。 但是所有的尝试都没有成功,它们都会抛出这个错误:

Cannot convert the string 'pack://application:,,,/Resources/Images/darkaurora.png' into a 'System.Windows.Media.ImageSource' object. Cannot locate resource 'resources/images/darkaurora.png'.  Error at object 'Image_Background' in markup file 'YearBook;component/Resources/ImageResources.xaml' Line 4 Position 6.

而且在代码的不同位置我得到了:

the file 'YearBook;component/Resources/Images/shadowdrop.png' is not a part of the project or its 'Build Action' property is not set to 'Resource'

那么,我做错了什么?


将构建操作设置为Resource,而不是Embedded Resource。 - devdigital
4个回答

34
当你将 BuildAction 设置为 Resource 时,它将作为嵌入的资源打包进程序集中。或者你可以将 BuildAction 设置为 Content,然后它将被打包到结果的 .xap 文件中。 你可以使用这两种 BuildActions 中的任何一种。通过将 BuildAction 设置为 Content ,你可以访问图片: "/Resources/Images/darkaurora.png"(必须以斜杠开头)。而当你使用 BuildAction Resource 时,你可以像这样访问图片:"/YearBook;component/Resources/Images/darkaurora.png"(assemblyname;component/relativepath)。希望这会有所帮助。

25
“嵌入式资源”和“资源”是不同的。如果你在 Reflector 或 ILSpy 中查看生成的程序集,你会发现它们被不同的方式包含在其中。作者询问如何使用“嵌入式资源”,而不是“资源”。 - BrainSlugs83
@ethicallogics 但是如果需要通过viewmodel绑定此资源怎么办?除了绑定到字符串路径之外还有其他选项吗? - nuclear sweet
6
当BuildAction为Resource时,组件名称前需要加上一个斜杠"/",例如:"/YearBook;component...."。详情请参考https://dev59.com/1XRC5IYBdhLWcg3wSu97。 - user3230660
2
我认为在资源作为BuildAction的情况下,应该是"pack://application:,,,/Resources/Images/darkaurora.png"。 - Ahm3d Said
1
由于此问题已被标记为WPF,因此关于资源与嵌入式资源的问题似乎很相关:https://dev59.com/AnI-5IYBdhLWcg3wR2Nr - HotN

1

对于那些使用Xamarin Forms并遇到这个问题的人,可以通过创建一个自定义的XAML标记扩展来解决,具体说明在这里:

https://learn.microsoft.com/en-us/xamarin/xamarin-forms/user-interface/images?tabs=windows

在“嵌入式图像”-“使用XAML”部分

引用自定义扩展

[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;
 }
}

使用说明引用

<?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:WorkingWithImages;assembly=WorkingWithImages"
   x:Class="WorkingWithImages.EmbeddedImagesXaml">
 <StackLayout VerticalOptions="Center" HorizontalOptions="Center">
   <!-- use a custom Markup Extension -->
   <Image Source="{local:ImageResource WorkingWithImages.beach.jpg}" />
 </StackLayout>
</ContentPage>

-1

ImageSource 无法实例化。

public abstract class ImageSource : Animatable, 
IFormattable

代码里有一个小的抽象,可能会导致问题。实际上,您的 XAML 尝试实例化 ImageSource 的实例,然后将元素(在本例中为 Uri)中的值分配给使用 ContentPropertyAttribute 标记的属性(??),并使用任何可用于将字符串转换为对象(再次是 ??)的转换器。

我认为您需要一个 BitmapSource

<BitmapImage 
    x:Key="Image_Background" 
    UriSource="/Images/darkaurora.png" />

4
实际上你这里翻译有误,因为 ImageSources 类有关联的 类型转换器,所以你可以在 XAML 中很好地声明它(请参见文档中的属性)。我不知道其它文档是否记录了这个问题,但是我认为你可以相信我的说法。你之所以会得到错误提示,仅仅是因为标签内部缺少内部 XML。 - H.B.
@H.B.:哎呀,你说得对。它将一个字符串转换为BitmapFrame(假设该字符串是指向某个图像文件的有效Uri)。 - user1228

-1
将构建操作设置为“资源”,而不是“嵌入式资源”。

1
但我希望它成为嵌入式资源。我需要在不显示图像的情况下部署应用程序。 - eric.itzhak
4
将其设置为资源将使其嵌入到程序集中。 - devdigital
我花了一些时间才弄清楚在哪里设置资源的构建操作。对于那些不知道devdigital指的是什么的人,这里有一个提示。在“解决方案资源管理器”中找到图标图像,右键单击并选择属性。应该显示图像的属性表。其中之一是“构建操作”。许多可能的设置 - “资源”和“嵌入式资源”是其中的两个选择。此外,注意属性“复制到输出目录”。关于此主题的其他建议也涉及到此属性。 - barrypicker

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接