wpf 当向集合中添加项或从集合中移除项时,具有[ObservableProperty]属性的ObservableCollection不会触发NotifyCanExecuteChanged

jdg4fx2g  于 2023-10-22  发布在  其他
关注(0)|答案(1)|浏览(216)

我在使用ObservableCollection和CommunityToolkit.Mvvm时遇到了一些问题,当集合被更改时(即,添加或删除的项目)MyCommand.NotifyCanExecuteChanged不会被调用。
我有这样的收藏:

  1. [ObservableProperty]
  2. [NotifyCanExecuteChangedFor(nameof(MyCommand))]
  3. private ObservableCollection<Foo> selectedItems = new();

视图中的绑定如下所示:{Binding SelectedItems, Mode=TwoWay}
ObservableProperty]生成的代码看起来像这样:

  1. /// <inheritdoc cref="selectedItems"/>
  2. [global::System.CodeDom.Compiler.GeneratedCode("CommunityToolkit.Mvvm.SourceGenerators.ObservablePropertyGenerator", "8.2.0.0")]
  3. [global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
  4. public global::System.Collections.ObjectModel.ObservableCollection<global::Foo> SelectedItems
  5. {
  6. get => selectedItems;
  7. [global::System.Diagnostics.CodeAnalysis.MemberNotNull("selectedItems")]
  8. set
  9. {
  10. if (!global::System.Collections.Generic.EqualityComparer<global::System.Collections.ObjectModel.ObservableCollection<global::Foo>>.Default.Equals(selectedItems, value))
  11. {
  12. OnSelectedItemsChanging(value);
  13. OnSelectedItemsChanging(default, value);
  14. OnPropertyChanging(global::CommunityToolkit.Mvvm.ComponentModel.__Internals.__KnownINotifyPropertyChangingArgs.SelectedItems);
  15. selectedItems = value;
  16. OnSelectedItemsChanged(value);
  17. OnSelectedItemsChanged(default, value);
  18. OnPropertyChanged(global::CommunityToolkit.Mvvm.ComponentModel.__Internals.__KnownINotifyPropertyChangedArgs.SelectedItems);
  19. MyCommand.NotifyCanExecuteChanged();
  20. }
  21. }
  22. }

我可以通过手动订阅ViewModel中的CollectionChanged事件并触发它来解决这个问题:

  1. this.SelectedItems.CollectionChanged += this.SelectedItemsCollectionChangedHandler;
  2. ...
  3. public void SelectedItemsCollectionChangedHandler(object? value, NotifyCollectionChangedEventArgs args)
  4. {
  5. if (args.Action == NotifyCollectionChangedAction.Add ||
  6. args.Action == NotifyCollectionChangedAction.Remove)
  7. {
  8. this.MyCommand.NotifyCanExecuteChanged();
  9. }
  10. }

然而,这似乎击败了在ObservableCollection上拥有ObservableProperty的观点。我是不是从根本上误解了ObservablyProperty在集合上的作用?在这种情况下,有没有办法避免手动订阅和处理CollectionChanged的样板?

nbewdwxp

nbewdwxp1#

正如您在为您的属性生成的代码(set中的最后一行)中所看到的,MyCommand.NotifyCanExecuteChanged仅在设置SelectedItems时(当您执行SelectedItems = ...时)才会被调用,而不是在其内容更改时(例如添加或删除项)。
Afaik NotifyCanExecuteChangedFor不会为您的情况下工作,我知道没有其他的解决方案比做更多或更少的你已经做了,手动处理CollectionChanged。

相关问题