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

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

我在使用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的样板?

nbewdwxp

nbewdwxp1#

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

相关问题