MAUI中扫描条码后ListView无法刷新UI的问题求助
解决MAUI ListView添加数据后UI不更新的问题
核心问题分析
List<T>不支持自动通知UI更新:你当前用的List<CollectionItem>未实现INotifyCollectionChanged接口,往集合里添加新元素时,UI无法感知到变化。- 变量名冲突导致赋值错误:条码扫描方法里的局部变量
items和类成员this.items重名,最后重新赋值ItemsSource时,用的是数据库查询返回的items,而非添加了新元素的类成员集合。
具体修复步骤
1. 替换List<T>为ObservableCollection<T>
将类里的List<CollectionItem>改成ObservableCollection<CollectionItem>,它会在集合元素增删改时自动通知UI刷新:
public partial class Sailor : ContentPage { // 替换List为ObservableCollection ObservableCollection<CollectionItem> items; internal class CollectionItem { public string Name { get; set; } public string Price { get; set; } public string Count { get; set; } } public Sailor() { InitializeComponent(); items = new ObservableCollection<CollectionItem> { new CollectionItem{ Name = "xx", Count = "2", Price = "10" }, new CollectionItem{ Name = "zz", Count = "2", Price = "10" } }; ListInvoice.ItemsSource = items; ListInvoice2.ItemsSource = items; ListInvoice3.ItemsSource = items; } }
2. 修正条码扫描方法里的变量名冲突
把数据库查询的局部变量名改成dbItems(避免和类成员items重名),并且不需要重新赋值ItemsSource,因为ObservableCollection会自动通知UI:
private async void CameraView_OnDetectionFinished(object sender, OnDetectionFinishedEventArg e) { // play peep // search in DB string returnedName = ""; string returnedPrice = ""; // 修改变量名,避免和类成员items冲突 var dbItems = await database.GetItemAsync(scannedBarcode); foreach (var item in dbItems) { Console.WriteLine("################"); returnedName = item.Art_Name; returnedPrice = item.Art_Price.ToString(); } // add new item to the list CollectionItem boughtItem = new CollectionItem { Name = returnedName, Count = "1", Price = returnedPrice }; Console.WriteLine(returnedName); Console.WriteLine(returnedPrice); Console.WriteLine(boughtItem.Name); Console.WriteLine(boughtItem.Price); // 直接添加到ObservableCollection,UI会自动刷新 this.items.Add(boughtItem); // 以下三行可删除,因为已绑定到ObservableCollection // ListInvoice.ItemsSource = items; // ListInvoice2.ItemsSource = items; // ListInvoice3.ItemsSource = items; }
3. 可选:给CollectionItem实现INotifyPropertyChanged
如果后续需要修改单个CollectionItem的属性(比如修改Count)让UI自动更新,需让CollectionItem实现INotifyPropertyChanged接口:
using System.ComponentModel; using System.Runtime.CompilerServices; internal class CollectionItem : INotifyPropertyChanged { private string _name; public string Name { get => _name; set { _name = value; OnPropertyChanged(); } } private string _price; public string Price { get => _price; set { _price = value; OnPropertyChanged(); } } private string _count; public string Count { get => _count; set { _count = value; OnPropertyChanged(); } } public event PropertyChangedEventHandler PropertyChanged; void OnPropertyChanged([CallerMemberName] string propertyName = null) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } }
原理说明
ObservableCollection<T>是MAUI中专门用于数据绑定的集合类型,它继承自Collection<T>并实现了INotifyCollectionChanged接口。当集合中的元素添加、移除或重置时,会触发CollectionChanged事件,绑定的ListView会监听这个事件并自动刷新UI。
内容的提问来源于stack exchange,提问作者Ani
相关产品推荐
相关产品推荐

