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

jtw3ybtb  于 2022-12-07  发布在  其他
关注(0)|答案(6)|浏览(206)

我的问题是,我可以把字符串图像绑定到图像源吗?2我有多个图像,图像会在条件下改变。3所以:
Xaml对Xamarin形式的影响:

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

代码隐藏C#

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

初始化组件部件:

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

图像位于便携项目上的“Images”文件夹中

但是这个,不起作用,也许我错了什么,但我不明白。有什么解决办法吗?
我尝试过使用ImageSource而不是字符串,但也不起作用。

qvsjd97n

qvsjd97n1#

我会把这个答案贴在这里,因为这是我一直在寻找的答案,我怀疑大多数其他人也是(谷歌目前把你带到这里,这目前不是很有帮助)。
如何使用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文件夹中。
EDIT2,很久以后:如果不明显的话,“prefix”和“suffix”只是随机字符串,SomeImage只需要返回图像的路径。SomeImageOtherProperty是视图模型类的成员,OtherProperty只是图像名称的基础(因为如果你事先知道整个名称,就不需要这个问题)。

piwo6bdm

piwo6bdm2#

你说:
图像位于便携项目的“Images”文件夹中
每个平台都有不同的资源和图像处理方法。Xamarin在每个平台上都有处理方法,例如Xamarin.iOS有嵌入式资源,而Xamarin.Android则使用Android资源来处理图像。
您应该将图像放在Xamarin.Forms的每个项目中,以便知道在每个平台中的何处查找它们。
如需详细信息,请参阅this

nfs0ujit

nfs0ujit3#

For using images from the PCL, check out this part in the Xamarin documentation.
You should make sure the Build action for each image is set to Embedded Resource .
Then, if you want to use them in XAML, specify a 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;
  }
}

You should then be able to use your images like this.

<?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>

Like mentioned in the comments, if you want this to work out of the box place them in the Resources folder of your respective platform project. This way you can also leverage the auto sizing mechanisms that are in place. To read more on this method see this page.
By adding them with the right naming convention in the right folder, you can simply refer to the filename and Xamarin.Forms will translate that to the right format for the platform.

z31licg0

z31licg04#

另一种方法是使用ValueConverter。这适用于预定义的图像集,尽管与Maverick解决方案相比,它不是最佳的代码大小。
添加到资源:

xmlns:conv="clr-namespace:MyProject.Converters"

<ContentPage.Resources>
    <col:ArrayList x:Key="States">
        <x:String>first.png</x:String>
        <x:String>second.png</x:String>
    </col:ArrayList>
    <conv:IntToImgConverter x:Key="IntToImgConverter" />
</ContentPage.Resources>

将ImageSource链接到转换器:

<Image>
    <Image.Source>
        <FileImageSource File="{Binding Path=State,
            Converter={StaticResource IntToImgConverter},
            ConverterParameter={StaticResource States}}"/>
    </Image.Source>
</Image>

State是视图模型的整数属性,它是数组中图像的序号。最后,转换器本身:

public class IntToImgConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value is int intVal && parameter is ArrayList strVal && strVal.Count > intVal)
            return strVal[intVal];
        throw new ArgumentException();
    }  
    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}
a0zr77ik

a0zr77ik5#

我想你可以做得更简单一点。这是我的工作。把图像放在每个平台的适当位置。例如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设置为图像的名称(不带扩展名),它就会更新。

carvr3hs

carvr3hs6#

我认为这不是最快的事情,但我找到了一种方法,只包括图像资源一次,在共享项目。
这样做的另一个好处是,文件在项目中的位置无关紧要,这对我来说很好,因为我经常移动文件。
它是一个名为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");

...您可以在运行时以任何方式动态分配它。

相关问题