如何为嵌入的图像资源实现绑定?

How can I implement binding for an Imbedded Image Resource?

  1. 我正在尝试将 ImageButton 源连接到我的 MainPage 中的可变字符串 属性。我不确定这样做是否正确。但是我正在尝试找到一种使用绑定表达式将两者绑定在一起的方法。
namespace MyNameSpace
{
    public partial class MainPage : ContentPage, INotifyPropertyChanged
    {

        public new  event PropertyChangedEventHandler PropertyChanged;
        public String One => "MyNameSpace.Images.Blue.jpg";

        public MainPage()
        {

            InitializeComponent();

        }
        protected override void OnPropertyChanged ([CallerMemberName] string name = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
        } 
   }
}

这是我创建的 MarkUpExtension,在我使用嵌入式图像资源时将字符串作为资源提供。

using System;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;

namespace MyNameSpace
{
    [ContentProperty("ResourceId")]
    public class EmbeddedImage : IMarkupExtension
    {
        public string ResourceId { get; set;}
        public object ProvideValue(IServiceProvider serviceProvider)
        {
            if (String.IsNullOrWhiteSpace(ResourceId))
                return null;
            return ImageSource.FromResource(ResourceId);
        }
    }
}

这就是我在 xaml...

中尝试将字符串绑定在一起的方式
<?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:MyNameSpace"
             x:Class="MyNameSpace.MainPage"
             x:Name = "Main">

    <StackLayout
        BindingContext="{x:Reference Name=Main }">
        
       <Image
           
           Source="{local:EmbeddedImage ResourceId = {Binding One}}">
          
       </Image>    
       
    </StackLayout>

</ContentPage>

显然它不起作用...我收到错误消息:

MainPage.xaml(13, 12): [XFC0009] No property, BindableProperty, or event found for "ResourceId", or mismatching type between value and property.

也许这不是解决问题的方法...有不同的方法吗?

您有一个可以更改的字符串,该字符串表示嵌入的资源(图像)

我的建议是使用Value Converters

首先,您必须修改字符串 属性 以在值更改时通知 UI

private string _one;
public string One
{
get=>_one; 
set{_one=value; NotifyPropertyChanged();}
}

然后你必须为转换器创建一个新的 class,这里将使用你的代码将字符串转换为 ImageSource

public class converter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            string ResourceId=value.ToString(); 
            if (String.IsNullOrWhiteSpace(ResourceId))
                return null;
            return ImageSource.FromResource(ResourceId);
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }

然后,就像任何其他转换器一样,将其添加到 App.xaml 中的应用程序资源中。这将根据您的名称 class 和命名空间

而有所不同
        <converters:converter x:Key="myConverter"/>

最后,图片的代码

<Image Source="{Binding One, Converter={StaticResource myConverter}}"/>

此外,如果您的应用程序不断增长,请考虑将 ViewModel 分离到另一个 class

不需要编写标记扩展。

  1. 创建一个 ImageSource 属性 并绑定到 xaml.
  2. 使用 ImageSource.FromStream 方法设置 属性(并传递嵌入的图像流)。

查看下面的示例。

代码隐藏

using System;
using System.IO;
using System.Reflection;

using Xamarin.Forms;

namespace App5
{
    public partial class MainPage
    {
        public MainPage()
        {
            InitializeComponent();
            SetImage();
        }

        private int Num = 1;
        private static readonly Assembly Assembly = typeof(MainPage).Assembly;

        private ImageSource _Source;
        public ImageSource Source
        {
            get => _Source;
            set
            {
                _Source = value;
                OnPropertyChanged();
            }
        }

        private void SetImage()
        {
            Source = ImageSource.FromStream(() => GetResourceStream($"{Num}.png"));
        }

        private void bChange_OnClicked(object sender, EventArgs e)
        {
            Num = Num == 1 ? 2 : 1;
            SetImage();
        }

        private static Stream GetResourceStream(string filename)
            => Assembly.GetManifestResourceStream($"App5.{filename}");
    }
}

XAML

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage
    x:Class="App5.MainPage"
    xmlns="http://xamarin.com/schemas/2014/forms"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    x:Name="This">

    <StackLayout>
        <Button Text="Change" Clicked="bChange_OnClicked" />
        <Image x:Name="img" Source="{Binding Source,Source={x:Reference This}}" />
    </StackLayout>
</ContentPage>

为了使示例工作,您需要将项目默认命名空间设置为 App5 并在根文件夹中嵌入文件名为 1.png2.png 的两个图像。