主ViewModel更新ObservableCollection后如何通知子ViewModel刷新视图?
问题与解决方案
我有一个主ViewModel(OpenedFileViewModel),其中的数据集合通过Store的事件更新。我想把这个集合传递给另一个ViewModel(FileDataListingViewModel)来在视图中展示数据,但不知道怎么通知子ViewModel,导致视图无法显示数据。我确认XAML里的所有绑定都是正确的,调试时各步骤的集合都包含正确数据。
原主ViewModel代码
public class OpenedFileViewModel : ViewModelBase { private DataGridStore _gridStore; public FileDataListingViewModel FileDataListingViewModel { get; set; } public ObservableCollection<ItemModel> ReadedItems => _gridStore?.ItemsCollection; public OpenedFileViewModel(DataGridStore _gridStore) { _gridStore.CurrentItemsChanged += OnCurrentFileDataChanged; // 数据变更时触发的事件 } private void OnCurrentFileDataChanged() { OnPropertyChanged(nameof(ReadedItems)); FileDataListingViewModel = new FileDataListingViewModel(ReadedItems); } }
原子ViewModel代码
public class FileDataListingViewModel : ViewModelBase { private ObservableCollection<ItemModel> _itmes; public ObservableCollection<ItemModel> Items { get { return _itmes; } set { _itmes = value; OnPropertyChanged(nameof(Items)); } } public FileDataListingViewModel(ObservableCollection<ItemModel> items) { Items = items; OnPropertyChanged(nameof(Items)); } }
问题根源与修复方案
问题点
- 主ViewModel的子ViewModel属性未触发变更通知:原代码中
FileDataListingViewModel是自动实现的getter/setter,赋值时没有调用OnPropertyChanged,视图无法感知到子ViewModel实例的替换。 - 重复创建子ViewModel实例:每次数据更新都新建子ViewModel,既浪费资源,也容易导致绑定上下文失效。
- 变量拼写错误:子ViewModel中
_itmes应为_items,属于代码规范问题。
修复后的主ViewModel
public class OpenedFileViewModel : ViewModelBase { private DataGridStore _gridStore; private FileDataListingViewModel _fileDataListingViewModel; // 给子ViewModel属性添加变更通知 public FileDataListingViewModel FileDataListingViewModel { get => _fileDataListingViewModel; set { _fileDataListingViewModel = value; OnPropertyChanged(nameof(FileDataListingViewModel)); } } public ObservableCollection<ItemModel> ReadedItems => _gridStore?.ItemsCollection; public OpenedFileViewModel(DataGridStore gridStore) { _gridStore = gridStore; _gridStore.CurrentItemsChanged += OnCurrentFileDataChanged; // 初始化子ViewModel,避免首次绑定为空 FileDataListingViewModel = new FileDataListingViewModel(ReadedItems); } private void OnCurrentFileDataChanged() { OnPropertyChanged(nameof(ReadedItems)); // 复用已有的子ViewModel,直接更新Items集合即可 FileDataListingViewModel.Items = ReadedItems; } }
修复后的子ViewModel
public class FileDataListingViewModel : ViewModelBase { private ObservableCollection<ItemModel> _items; public ObservableCollection<ItemModel> Items { get => _items; set { _items = value; OnPropertyChanged(nameof(Items)); } } public FileDataListingViewModel(ObservableCollection<ItemModel> items) { Items = items; // 构造函数赋值已触发set中的OnPropertyChanged,无需重复调用 } }
核心说明
- 确保主ViewModel的
FileDataListingViewModel属性在变更时触发OnPropertyChanged,让视图感知到子ViewModel的变化。 - 优先复用子ViewModel实例,直接更新其
Items属性,避免频繁创建对象带来的绑定问题。 - 修正变量拼写错误,保证代码可读性和规范性。
内容的提问来源于stack exchange,提问作者iliyars
相关产品推荐
相关产品推荐

