ObservableCollection<String>未更新:跨平台与Android项目联动异常
问题根源分析
你遇到的核心问题是跨平台层和Android层操作的不是同一个BluetoothItems实例,导致集合变化完全无法同步:
每次调用
DependencyService.Get<ISlateBluetoothItems>().test()时,你大概率是在Android实现里直接返回了新的BluetoothItems对象(比如return new BluetoothItems();)。这就意味着:- 跨平台层绑定监听的
NewRef是一个独立实例 - Android端调用
AddThis()的是另一个完全无关的实例
两者没有任何关联,自然监听不到集合变化。
- 跨平台层绑定监听的
额外的冗余操作:你的
CollectionChanged事件处理里又重新获取了一次实例并赋值给ItemsSource,这不仅没必要,还会让UI绑定到新的实例,进一步切断和原始集合的关联。
修复方案
第一步:让ISlateBluetoothItems维护单例实例
修改Android端的ISlateBluetoothItems实现,确保始终返回同一个BluetoothItems实例:
// Android项目中的实现类 [assembly: Dependency(typeof(SlateBluetoothItemsImpl))] namespace ThoughtCastRewrite.Droid.BluetoothX { public class SlateBluetoothItemsImpl : ISlateBluetoothItems { // 维护全局唯一的实例 private BluetoothItems _bluetoothItemsInstance; public BluetoothItems test() { if (_bluetoothItemsInstance == null) { _bluetoothItemsInstance = new BluetoothItems(); } return _bluetoothItemsInstance; } } }
第二步:优化跨平台层的代码逻辑
只获取一次实例,绑定并监听事件,不需要重复赋值ItemsSource(ObservableCollection本身会自动通知UI更新):
// 跨平台项目中的代码 private BluetoothItems _bluetoothItems; // 在页面初始化时执行(比如OnAppearing方法) protected override void OnAppearing() { base.OnAppearing(); // 只获取一次单例实例 _bluetoothItems = DependencyService.Get<ISlateBluetoothItems>().test(); // 绑定一次ItemsSource即可 listView.ItemsSource = _bluetoothItems.testThing; // 监听集合变化事件 _bluetoothItems.testThing.CollectionChanged += TestThing_CollectionChanged; } private void TestThing_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e) { Console.WriteLine("working"); // 不需要重新赋值ItemsSource,ObservableCollection会自动触发UI更新 }
第三步:确保Android端操作的是同一个实例
在Android端需要修改集合时,通过同一个单例实例调用AddThis():
// Android项目中修改集合的代码 var bluetoothItems = DependencyService.Get<ISlateBluetoothItems>().test(); bluetoothItems.AddThis();
额外编码规范建议
把BluetoothItems中的testThing字段改成属性,遵循C#的编码规范,也能避免意外的访问问题:
public class BluetoothItems { public ObservableCollection<string> TestThing { get; private set; } public BluetoothItems() { TestThing = new ObservableCollection<string>(); TestThing.Add("wtf?"); } public void AddThis() { TestThing.Add("ok"); } }
(记得同步修改跨平台层的代码,把testThing改成TestThing)
这样调整后,跨平台层和Android层操作的就是同一个ObservableCollection实例,集合变化时CollectionChanged事件会正常触发,UI也会自动更新。
内容的提问来源于stack exchange,提问作者David Kachlon
相关产品推荐
相关产品推荐

