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

Posted

技术标签:

【中文标题】如何从 XAML 引用嵌入式资源?【英文标题】:How to refer to Embedded Resources from XAML? 【发布时间】:2012-03-14 05:53:44 【问题描述】:

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

当我将 Build Action 设置为 Embedded Resource 我通过代码找到资源不可用的错误,并要求我将构建操作设置为 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'

那么,我做错了什么?

【问题讨论】:

【参考方案1】:

当您将 BuildAction 设置为 Resource 时,它将作为程序集中的嵌入资源。 或者您可以将 BuildAction 设置为 Content,然后它将捆绑到生成的 .xap 文件中。 您可以使用这些 BuildAction 中的任何一个。通过将 BuildAction 设置为 Content,您可以像这样访问 Image: "/Resources/Images/darkaurora.png"(必须以斜线开头)。当您使用 BuildAction Resource 时,您可以以"/YearBook;component/Resources/Images/darkaurora.png"(程序集名称;组件/相对路径)访问图像。希望这会有所帮助。

【讨论】:

“嵌入式资源”和“资源”不同。如果您查看 Reflector 或 ILSpy 中生成的程序集,您会发现它们以不同的方式包含在内。作者问如何用“嵌入式资源”而不是“资源”来做到这一点。 @ethicallogics 但是如果需要通过视图模型绑定这个资源怎么办?除了绑定到字符串路径还有其他选择吗? 当 BuildAction 为 Resource:"/YearBook;component...." 时,您需要在程序集名称上使用前导斜杠。见***.com/questions/347614/wpf-image-resources 我认为在 Resource as a BuildAction 的情况下应该是 "pack://application:,,,/Resources/Images/darkaurora.png" 由于此问题已被标记为 WPF,因此有关资源与嵌入式资源的问题似乎相关:***.com/questions/1934826【参考方案2】:

对于那些使用 xamarin 表单并遇到此问题的人,可以通过创建此处说明的自定义 xaml 标记扩展来完成:

https://docs.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>

【讨论】:

【参考方案3】:

将构建操作设置为 Resource,而不是 Embedded Resource

【讨论】:

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

ImageSource 无法实例化。

public abstract class ImageSource : Animatable, 
IFormattable

里面有一个小小的abstract,会让你的一天一团糟。您的 xaml 实际上是在尝试实例化 ImageSource 的实例,然后使用任何可以将字符串转换为一个对象(再次,??)。

我想你想要一个BitmapSource。

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

【讨论】:

其实你弄错了,你可以在XAML中声明ImageSources就好了,因为这个类有一个type converter与之关联(参见the docs中的属性)。不能告诉你记录在哪里,但我认为你可以相信我。您收到该错误只是因为缺少标记的内部 XML。 @H.B.:哎哟。你说得对。它将字符串转换为 BitmapFrame(假设字符串是指向某处图像文件的有效 Uri)。

以上是关于如何从 XAML 引用嵌入式资源?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用嵌入在 XAML 中的 Roboto Thin?

在 c# 中从其他资源中引用嵌入式资源

如何从 CSS 中引用嵌入的图像?

如何将 WPF 图像资源文件夹写入磁盘?

如何将Skyline66嵌入WPF中

存储 WPF 图像资源