在xamarin表单上动态绑定图像源

时间:2017-04-11 10:56:23

标签: c# image xamarin binding xamarin.forms

我的问题是,我可以将字符串图像绑定到图像源吗?我有多个图像,如果条件,图像将会改变。所以:

Xamal表示Xaml:

<Image Source="{Binding someImage}" Aspect="Fill" Grid.Row="2"></Image>

Codebehind c#

   public String someImage;
    public String SomeImage
    {
        set
        {
            if (someImage != value)
            {
                someImage = value;                                        
            }
        }
        get
        {
            return someImage;
        }
    }

InitializeComponent部分:

if(true)
            {
                someImage = "backgroundListViewGren.png";
            }
            else
            {
                someImage = "backgroundListViewRed.png";
            }

图片位于便携式项目的“图片”文件夹中

但是,这不起作用,也许我不会做什么,但我不明白。 任何解决方案?

我尝试使用ImageSource而不是字符串,但也不用。

5 个答案:

答案 0 :(得分:13)

我会在这里发布这个答案,因为它是我正在寻找的那个,我怀疑大多数人都是(并且谷歌目前在这里指导你,目前这不是非常有帮助的。)

如何使用XAML绑定图像:

XAML:

<Image>
    <Image.Source>
        <FileImageSource File="{Binding SomeImage}" />
    </Image.Source>
</Image>

然后在ViewModel中,C#:

public string SomeImage
{
    get { return string.Format("prefix-{0}-suffix.png", OtherProperty); }
}

您可以使用更新,更好,但基本相同的c#代替上述内容:

public string SomeImage => $"prefix-{OtherProperty}-suffix.png";

这当然是设置它的最简单方法,IMO :)。

编辑:不言而喻,但图片显然应位于每个平台项目的Resources文件夹中。

答案 1 :(得分:3)

你说:

  

图像在&#34;图像&#34;便携式项目上的文件夹

每个平台都有不同的资源和图像方法。 Xamarin处理每个平台,例如Xamarin.iOS有嵌入资源,而Xamarin.Android使用Android资源进行图像处理。

您应该将图像放在Xamarin.Forms的每个项目中,以了解在每个平台中查找它们的位置。

有关详细信息,请查看this

答案 2 :(得分:3)

要使用PCL中的图像,请在Xamarin documentation

中查看此部分

您应该确保每张图片的Build action都设置为Embedded Resource

然后,如果要在XAML中使用它们,请指定MarkupExtension

[ContentProperty ("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);

    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>

如评论中所述,如果您希望这个开箱即用,请将它们放在各自平台项目的Resources文件夹中。这样您还可以利用现有的自动调整大小机制。要详细了解此方法,请参阅此page

通过在右侧文件夹中添加正确的命名约定,您可以简单地引用文件名,Xamarin.Forms会将其转换为平台的正确格式。

答案 3 :(得分:0)

我认为你可以做得更简单一些。这正在我的工作。 将图像放在每个平台上的适当位置,例如。 Android上的资源/可绘制

在您的Xaml中:

<Image Source="{Binding someImage}" Aspect="Fill" Grid.Row="2"></Image>

在您的视图模型中:

private string _someImage = "icon_eye_hidden";
    public string someImage
    {

        get => this._someImage;
        set
        {

            if (this._someImage == value) return;

            this._someImage = value;
            this.RaisePropertyChanged(() => this.someImage);
        }
    }

然后只需将someImage设置为图像名称(不带扩展名),它应该更新。

答案 4 :(得分:0)

我认为这不是最快的事情,但是我找到了一种在共享项目中仅包含一次图像资源的方法。

这还具有一个优点,即文件在您的项目中的位置无关紧要,这对我来说是有益的,因为我倾向于频繁地移动内容。

这是一个名为EmbeddedSourceror的类。它基本上只是根据需要查找并返回资源:

public class EmbeddedSourceror
{
    //NOTE: if there are resources *anywhere* with identical names, this will only return the *first* one it finds, so don't duplicate names
    public static Xamarin.Forms.ImageSource SourceFor(string filenameWithExtension)
    {       
        var resources = typeof(EmbeddedSourceror).GetTypeInfo().Assembly.GetManifestResourceNames();

        var resourceName = resources.First(r => r.EndsWith(filenameWithExtension, StringComparison.OrdinalIgnoreCase));

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

用法:

假设在XAML中定义的图像元素为centerImageElement:

centerImageElement.Source = EmbeddedSourceror.SourceFor("centerimage.png");

...,您可以在运行时随意分配它。