重新创建ObservableCollection时取消ListView选中项避免空引用异常
解决ListView重新绑定ObservableCollection时的NullReferenceException问题
问题根源
你的问题核心在于重新赋值myCollection时,旧的selectedItem引用的是原集合中的对象,ListView更新ItemsSource后会尝试同步这个已不存在的对象;再加上selectedItem属性未实现属性变更通知,导致绑定逻辑触发空引用异常。
解决方案
1. 给ViewModel实现INotifyPropertyChanged接口
selectedItem和myCollection属性必须触发PropertyChanged事件,让UI及时感知状态变化,这是解决问题的核心:
public class YourViewModel : INotifyPropertyChanged { private Field selecteditem; public Field selectedItem { get { return selecteditem; } set { if (selecteditem != value) { selecteditem = value; OnPropertyChanged(nameof(selectedItem)); } } } private ObservableCollection<Field> myCollection; public ObservableCollection<Field> myCollection { get { return myCollection; } set { if (myCollection != value) { myCollection = value; OnPropertyChanged(nameof(myCollection)); } } } // 实现INotifyPropertyChanged的标准代码 public event PropertyChangedEventHandler PropertyChanged; protected virtual void OnPropertyChanged(string propertyName) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } // 更新集合的方法 public void RefreshCollection() { // 先清空选中项并触发通知 selectedItem = null; // 再赋值新集合 myCollection = customClass.fillCollection(selectedLightColor, selectedDarkColor); } }
2. 明确XAML绑定模式(可选但推荐)
给SelectedItem绑定加上Mode=TwoWay,确保UI和ViewModel的状态双向同步:
<ListView ItemsSource="{Binding myCollection}" SelectedItem="{Binding selectedItem, Mode=TwoWay}">
3. 复用ObservableCollection实例(替代直接赋值)
如果不需要全新集合实例,可清空原集合再添加新元素,避免绑定上下文重置:
public void RefreshCollection() { selectedItem = null; myCollection.Clear(); var newItems = customClass.fillCollection(selectedLightColor, selectedDarkColor); foreach (var item in newItems) { myCollection.Add(item); } }
4. 检查fillCollection的返回值
确保方法不会返回null,避免直接赋值空集合引发异常:
var newCollection = customClass.fillCollection(selectedLightColor, selectedDarkColor); myCollection = newCollection ?? new ObservableCollection<Field>();
内容的提问来源于stack exchange,提问作者freasy
相关产品推荐
相关产品推荐

