ListView绑定ObservableCollection无数据显示问题求助
看起来你的ListView不显示数据的问题大概率出在以下几个地方,咱们逐个排查:
1. 接口ISerialsPortsViewModel未定义SerialPortName属性
你绑定的SerialsPorts是ObservableCollection<ISerialsPortsViewModel>类型,而TextCell绑定的是SerialPortName。如果你的ISerialsPortsViewModel接口里没有声明SerialPortName这个属性,XAML的数据绑定系统无法识别这个属性,自然不会显示内容。
解决方法:
确保ISerialsPortsViewModel接口包含SerialPortName属性的定义:
public interface ISerialsPortsViewModel : INotifyPropertyChanged { string SerialPortName { get; set; } }
记得让SerialsPortsViewModel正确实现这个接口。
2. 非UI线程更新ObservableCollection
OnDeviceSerialsPortsInfoUpdated是通过事件触发的回调,这个回调大概率是在非UI线程执行的。而ObservableCollection的集合变更通知需要在UI线程发送,否则UI不会感知到集合的变化,ListView也就不会更新。
解决方法:
在添加元素到SerialsPorts时,切换到UI线程执行。在Xamarin.Forms里可以用Device.BeginInvokeOnMainThread:
private void OnDeviceSerialsPortsInfoUpdated(object sender, IDeviceSerialsPortsInfoEventArgs e) { Device.BeginInvokeOnMainThread(() => { foreach(string device in e.DeviceSerialsPorts.Devices) { ISerialsPortsViewModel serialsPortsViewModel = new SerialsPortsViewModel(device); SerialsPorts.Add(serialsPortsViewModel); SerialTest += device + Environment.NewLine; } }); }
3. 页面未正确设置BindingContext
如果你的页面没有把BindingContext设置为BrightnessSerialsPortsViewModel的实例,那么ListView的ItemsSource="{Binding SerialsPorts}"根本找不到对应的数据源。
解决方法:
在页面的构造函数或者XAML里设置BindingContext:
- 代码方式(比如在Page的构造函数):
public YourPage() { InitializeComponent(); BindingContext = new BrightnessSerialsPortsViewModel(); }
- XAML方式:
<ContentPage.BindingContext> <local:BrightnessSerialsPortsViewModel /> </ContentPage.BindingContext>
(记得要在XAML顶部添加local命名空间,指向ViewModel所在的程序集)
额外检查点
- 确认
SerialsPortsViewModel的SerialPortName属性确实被正确赋值,并且OnPropertyChanged在setter里被调用了(你的代码里已经做了这一步,这点没问题)。 - 可以给ListView加上
HasUnevenRows="True"或者设置RowHeight,有时候内容存在但因为行高为0导致看不见。
先按这几个步骤排查,应该能解决你的问题。
内容的提问来源于stack exchange,提问作者AccountForWorks

