You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为什么修改元素属性时Xamarin CollectionView未更新UI?

问题原因

  1. 你定义了集合同步回调ObservableCollectionCallback,但没有通过BindingOperations.EnableCollectionSynchronization将其注册到ObservableCollection,导致跨线程操作集合时绑定引擎无法正确接收变更通知。
  2. 你通过索引修改集合元素的方式存在索引漂移风险:你在读取锁中获取到元素索引后,若集合在主线程执行修改前发生了增删操作,索引会指向错误的元素,导致实际修改的不是目标对象。
  3. 手动重复赋值FrameBg属于冗余操作,可能覆盖预期逻辑。

解决步骤

  1. 注册集合同步回调
    在初始化Lista集合后新增注册代码,让绑定引擎感知你自定义的线程同步逻辑:
public static ObservableCollection<ChatMembers> Lista { get; set; } = new ObservableCollection<ChatMembers>();
public static ReaderWriterLockSlim valuesLock = new ReaderWriterLockSlim();

// 新增这行注册代码
BindingOperations.EnableCollectionSynchronization(Lista, valuesLock, ObservableCollectionCallback);
  1. 直接操作目标元素实例,不要使用索引
    你已经在读取锁中拿到了目标ChatMembers实例,直接修改该实例的属性即可,不需要再通过索引从集合中取元素:
_ = Device.InvokeOnMainThreadAsync(() =>
{
    valuesLock.EnterWriteLock();
    try
    {
        // 直接修改已拿到的item对象,不要用Lista[indexof]
        item.Lida = true;
        // 删掉手动赋值FrameBg的代码,Lida的set方法中已经自动更新了FrameBg
    }
    finally { valuesLock.ExitWriteLock(); }
});
  1. 优化属性变更通知(可选,减少出错概率)
    给NotifyPropertyChanged方法添加CallerMemberName特性,避免硬编码属性名字符串带来的拼写错误:
using System.Runtime.CompilerServices;

void NotifyPropertyChanged([CallerMemberName] string propName = "")
{
    PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propName));
}

修改后属性的set方法可以简化为:

public bool Lida
{
    get { return _Lida; }
    set
    {
        _Lida = Convert.ToBoolean(value);
        FrameBg = !_Lida ? (UserFrom == MainPage.MeuID ? WhiteAlpha : GreenAlpha) : WhiteAlpha;
        // 不需要传属性名,自动获取
        NotifyPropertyChanged();
    }
}
  1. 检查辅助属性
    确认ChatMembers类中的UserFrom属性已正确定义并赋值,避免FrameBg计算逻辑异常。

  2. 确认集合实例一致性
    检查代码中是否存在重复给Lista赋值新实例的逻辑,确保CollectionView绑定的Lista和你修改的Lista是同一个实例。


内容的提问来源于stack exchange,提问作者Éder Rocha

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.07 03:27:00