如何为嵌入的图像资源实现绑定?
How can I implement binding for an Imbedded Image Resource?
- 我正在尝试将 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
不需要编写标记扩展。
- 创建一个
ImageSource
属性 并绑定到 xaml.
- 使用
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.png
和 2.png
的两个图像。
- 我正在尝试将 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
不需要编写标记扩展。
- 创建一个
ImageSource
属性 并绑定到 xaml. - 使用
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.png
和 2.png
的两个图像。