简体   繁体   English

Xamarin形式的EmbeddedImage:如何在XAML中绑定它

[英]EmbeddedImage in Xamarin Forms: how to bind it in XAML

I am trying to follow the Xamarin documentation about Embedded Images: https://developer.xamarin.com/guides/xamarin-forms/working-with/images/#Embedded_Images 我试图遵循有关嵌入式图像的Xamarin文档: https : //developer.xamarin.com/guides/xamarin-forms/working-with/images/#Embedded_Images

This is the code snippet that I use in my portable application: 这是我在便携式应用程序中使用的代码片段:

var embeddedImage = new Image { Aspect = Aspect.AspectFit };
embeddedImage.Source = ImageSource.FromResource("<MyNamespace>.<MyFolder>.imageFileName.jpg");

listItem.EmbeddedImage = embeddedImage;

Now I am trying to bind it in XAML, as part of a ListView ( note: the <Image Source="{Binding EmbeddedImage}" /> part is probably wrong) : 现在,我尝试将其作为ListView一部分在XAML中进行绑定( 注意: <Image Source="{Binding EmbeddedImage}" />部分可能是错误的):

<ListView  x:Name="listView">
  <ListView.ItemTemplate>
    <DataTemplate>
      <ViewCell>
        <StackLayout BackgroundColor="#eee"
        Orientation="Vertical">
          <StackLayout Orientation="Horizontal">
            <Image Source="{Binding EmbeddedImage}" /> // This is most likely wrong since it doesn't work       
          </StackLayout>
        </StackLayout>
      </ViewCell>
    </DataTemplate>
  </ListView.ItemTemplate>
</ListView>

I've tested this with <Image Source="{Binding ImageUrl}" /> and it works, so the rest of the code seems to be working as it should. 我已经使用<Image Source="{Binding ImageUrl}" />并且可以正常工作,因此其余代码似乎可以正常工作。


Edit: 编辑:

Someone suggested this post as a solution: 有人建议将此帖子作为解决方案:

How to load an image to a ImageCell on Xamarin.Forms? 如何在Xamarin.Forms上将图像加载到ImageCell?

But the accepted answer there was: 但是那里的公认答案是:

The images go into your "native" projects 图片进入您的“本地”项目

...but actually the Xamarin documentation says that it can be done inside the portable project (so you wouldn't need to copy the same images/icons through all the "native" projects). ...但是实际上Xamarin文档说它可以在可移植项目中完成(因此您不需要通过所有“本地”项目复制相同的图像/图标)。

I know that putting them in every subproject would probably work, but that's not the point of my question. 我知道将它们放在每个子项目中可能会起作用,但这不是我的问题的重点。

You can access the resource directly in xaml by using pack://application uri. 您可以使用pack://application uri在xaml中直接访问资源。

<ListView  x:Name="listView">
  <ListView.ItemTemplate>
    <DataTemplate>
      <ViewCell>
        <StackLayout BackgroundColor="#eee"
        Orientation="Vertical">
          <StackLayout Orientation="Horizontal">
            <Image Source="pack://application:,,,/{AssemblyName};component/Images/MyImage.png" />     
          </StackLayout>
        </StackLayout>
      </ViewCell>
    </DataTemplate>
  </ListView.ItemTemplate>
</ListView>

I've combed my hair out over this, and the problem is that Microsoft doesn't tell you the whole story in the Images docs. 我为此进行了梳理,问题是Microsoft并未在Images文档中告诉您整个故事。 You have to go over to the Files docs to understand why it won't work. 您必须转到“文件”文档以了解为什么它不起作用。

Yes, you can use embedded resources in the shared project directory, but apparently under only one of two conditions: 是的,您可以在共享项目目录中使用嵌入式资源,但是显然只能在以下两种情况之一中使用:

  1. You have to use a Markup Extension and then directly specify the resource path in Xaml, a la: <Image Source="{local:ImageResource ProjectName.Images.flower.jpg"/> 您必须使用标记扩展,然后直接在Xaml中指定资源路径例如: <Image Source="{local:ImageResource ProjectName.Images.flower.jpg"/>
  2. You write compiler directives in the code-behind that customize the beginning of the ResourceID per-platform. 您在后面的代码中编写了编译器指令,这些指令自定义每个平台的ResourceID的开头。

Option 1 requires hard-coding the path, so you can't use a dynamically-assigned image, and Option 2 wrecks the whole point of trying to write cross-platform code. 选项1需要对路径进行硬编码,因此您不能使用动态分配的图像,而选项2破坏了尝试编写跨平台代码的整个工作。


WAY HUGE EDIT: May be solved 巨大的编辑:可以解决

This post on the Xamarin forums made a huge difference for me: https://forums.xamarin.com/discussion/17953/helpful-shared-project-image-information Xamarin论坛上的这篇文章对我产生了巨大的影响: https : //forums.xamarin.com/discussion/17953/helpful-shared-project-image-information

note: the first post basically gives you all the code you need, but a little bit down in the thread there's some advice about project configurations that may be necessary for it to work correctly. 注意:第一篇文章基本上为您提供了所需的所有代码,但是在线程中稍稍有些不足,可能需要一些有关项目配置的建议才能使其正常工作。

It basically introduces some custom code that programmatically derives the resource ID during runtime, so it's cross-platform code that customizes itself to whatever platform is currently running it. 它基本上引入了一些自定义代码,这些自定义代码在运行时以编程方式派生资源ID,因此,它是跨平台代码,可针对当前正在运行的任何平台进行自定义。 Working beautifully for me! 为我而努力! Here's the version of the suggested approach that I'm using: 这是我正在使用的建议方法的版本:

using System.Linq;
using System.Reflection;
using System.Diagnostics;
using System;

namespace Helpers
{
    public class EmbeddedSourceror
    {
        public static Xamarin.Forms.ImageSource SourceFor(string pclFilePathInResourceFormat)
        {
            var resources = typeof(EmbeddedSourceror).GetTypeInfo().Assembly.GetManifestResourceNames();
            var resourceName = resources.Single(r => r.EndsWith(pclFilePathInResourceFormat, StringComparison.OrdinalIgnoreCase));
            Debug.WriteLine("EmbeddedSourceror: resourceName string is " + resourceName);

            return Xamarin.Forms.ImageSource.FromResource(resourceName);
        }
    }
}

This lets you write the Xaml code in a totally normal way, such as: 这使您可以以完全正常的方式编写Xaml代码,例如:

<Image
            x:Name         ="backingImage"
            Aspect         ="AspectFill" />

And in the code-behind all you have to do is: 在代码背后,您要做的就是:

    backingImage.Source = EmbeddedSourceror.SourceFor("flower.jpg");

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM