如何将ImageSource绑定到ObservableCollection元素属性及实现属性变更通知
Xamarin.Forms ImageSource绑定ObservableCollection元素属性解决方案
修复步骤
1. 完善MainPage的INotifyPropertyChanged实现,将_hand改为公共可通知属性
XAML无法绑定私有字段,需改为公共属性,且赋值时触发变更通知:
public partial class MainPage : ContentPage, INotifyPropertyChanged { // 实现INotifyPropertyChanged事件 public event PropertyChangedEventHandler PropertyChanged; protected void OnPropertyChanged(string propertyName) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } private ObservableCollection<Card> _hand; // 公共绑定属性 public ObservableCollection<Card> Hand { get => _hand; set { _hand = value; OnPropertyChanged(nameof(Hand)); } } public MainPage() { // 先初始化界面再初始化数据 InitializeComponent(); Init(); } private void Init() { Hand = new ObservableCollection<Card>() { new Card("image1.jpg"), new Card("image2.jpg"), new Card("image3.jpg"), new Card("image4.jpg") }; } // 切换元素的方法示例 public void ChangeCard() { // 直接替换集合内元素,ObservableCollection自带集合变更通知,无需额外触发 Hand[0] = new Card("new_image.jpg"); } }
对应的XAML绑定路径改为Hand,替换原有的_hand:
Source="{Binding Hand[0].ResourceId , Converter={StaticResource StringToSourceConverter}}"
2. 修正转换器名称匹配问题
你的转换器类名为ToStringConverter,XAML中引用的键名为StringToSourceConverter,需统一,且要在页面资源中声明转换器实例:
<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" Padding="5,20,5,5" BindingContext="{x:Reference Name=Main }"> <!-- 添加页面资源,声明转换器 --> <ContentPage.Resources> <local:ToStringConverter x:Key="StringToSourceConverter" /> </ContentPage.Resources> <!-- 原有Grid代码 --> </ContentPage>
3. 按需给Card类实现INotifyPropertyChanged
如果需要修改已存在的Card对象的ResourceId属性,则Card类也需要实现属性通知:
public class Card : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; protected void OnPropertyChanged(string propertyName) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } private string _resourceId; public string ResourceId { get => _resourceId; set { _resourceId = value; OnPropertyChanged(nameof(ResourceId)); } } public Card(string resourceId) { ResourceId = resourceId; } }
PropertyChanged触发位置说明
- 仅增删/替换集合内元素:不需要额外触发PropertyChanged,ObservableCollection自带的
CollectionChanged事件会自动通知UI更新 - 重新给
Hand属性赋值整个新的ObservableCollection:在Hand属性的setter中触发,也就是上述MainPage代码中已实现的逻辑 - 修改单个Card对象的ResourceId:在Card类的ResourceId属性的setter中触发,如上述Card类代码实现
额外注意点
ImageSource.FromResource方法要求传入的资源ID是带命名空间的完整路径,比如你的图片放在项目的Images文件夹下,正确的ResourceId应为MyNameSpace.Images.image1.jpg,否则会返回空资源。
内容的提问来源于stack exchange,提问作者Luca Hafer
相关产品推荐
相关产品推荐

