我在使用ObservableCollection和CommunityToolkit.Mvvm
时遇到了一些问题,当集合被更改时(即,添加或删除的项目)MyCommand.NotifyCanExecuteChanged
不会被调用。
我有这样的收藏:
[ObservableProperty]
[NotifyCanExecuteChangedFor(nameof(MyCommand))]
private ObservableCollection<Foo> selectedItems = new();
视图中的绑定如下所示:{Binding SelectedItems, Mode=TwoWay}
从ObservableProperty]
生成的代码看起来像这样:
/// <inheritdoc cref="selectedItems"/>
[global::System.CodeDom.Compiler.GeneratedCode("CommunityToolkit.Mvvm.SourceGenerators.ObservablePropertyGenerator", "8.2.0.0")]
[global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
public global::System.Collections.ObjectModel.ObservableCollection<global::Foo> SelectedItems
{
get => selectedItems;
[global::System.Diagnostics.CodeAnalysis.MemberNotNull("selectedItems")]
set
{
if (!global::System.Collections.Generic.EqualityComparer<global::System.Collections.ObjectModel.ObservableCollection<global::Foo>>.Default.Equals(selectedItems, value))
{
OnSelectedItemsChanging(value);
OnSelectedItemsChanging(default, value);
OnPropertyChanging(global::CommunityToolkit.Mvvm.ComponentModel.__Internals.__KnownINotifyPropertyChangingArgs.SelectedItems);
selectedItems = value;
OnSelectedItemsChanged(value);
OnSelectedItemsChanged(default, value);
OnPropertyChanged(global::CommunityToolkit.Mvvm.ComponentModel.__Internals.__KnownINotifyPropertyChangedArgs.SelectedItems);
MyCommand.NotifyCanExecuteChanged();
}
}
}
我可以通过手动订阅ViewModel中的CollectionChanged
事件并触发它来解决这个问题:
this.SelectedItems.CollectionChanged += this.SelectedItemsCollectionChangedHandler;
...
public void SelectedItemsCollectionChangedHandler(object? value, NotifyCollectionChangedEventArgs args)
{
if (args.Action == NotifyCollectionChangedAction.Add ||
args.Action == NotifyCollectionChangedAction.Remove)
{
this.MyCommand.NotifyCanExecuteChanged();
}
}
然而,这似乎击败了在ObservableCollection
上拥有ObservableProperty
的观点。我是不是从根本上误解了ObservablyProperty
在集合上的作用?在这种情况下,有没有办法避免手动订阅和处理CollectionChanged
的样板?
1条答案
按热度按时间nbewdwxp1#
正如您在为您的属性生成的代码(set中的最后一行)中所看到的,
MyCommand.NotifyCanExecuteChanged
仅在设置SelectedItems时(当您执行SelectedItems = ...
时)才会被调用,而不是在其内容更改时(例如添加或删除项)。Afaik NotifyCanExecuteChangedFor不会为您的情况下工作,我知道没有其他的解决方案比做更多或更少的你已经做了,手动处理CollectionChanged。