在 Blazor 应用程序中实现 MVVM 模式时如何处理绑定 ObservableCollections?

How handle binding ObservableCollections when implementing MVVM Pattern in a blazor application?

由于我的 blazor 应用程序中的页面 classes 变得有些冗长和凌乱,而且我最初是从 WPF 开发而来的,我想,我看一下 MVVM-ifying 我的应用程序。

预赛:

这是我的 ViewModelBase

public abstract class ViewModelBase : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    protected void SetProperty<T>(ref T storage, T value,
        [CallerMemberName] string property = null)
    {
        if (object.Equals(storage, value)) return;
        storage = value;
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(property));
    }
}

下面是相关的 ViewModel 和依赖注入系统的相应接口:

public class DatasetManagerViewModel : ViewModelBase, IDatasetManagerViewModel
{
    private DatasetModel _selectedDataset;
    public DatasetModel SelectedDataset 
    { 
        get { return _selectedDataset;}
        set { SetProperty(ref _selectedDataset, value); }
    }

    public ObservableCollection<ImageModel> DatasetFiles { get; set; } = new();
}

public interface IDatasetManagerViewModel
{
    event PropertyChangedEventHandler PropertyChanged;
    ObservableCollection<ImageModel> DatasetFiles { get; set; }
    DatasetModel SelectedDataset { get; set; }
}

在View/PageClass中是这样实现的:

[Inject]
protected IDatasetManagerViewModel ViewModel { get; private set; }

private async void OnPropertyChangedHandler(object sender, PropertyChangedEventArgs e)
{
    await InvokeAsync(() =>
    {
        StateHasChanged();
    });
}

protected override async Task OnInitializedAsync()
{
    ViewModel.PropertyChanged += OnPropertyChangedHandler;   
    await base.OnInitializedAsync();
}
// also unsubscribe event after disposal

问题:

这在正常属性的情况下工作正常,例如在上述 SelectedDataset 的情况下。 但是,我想知道最好的方法是将 ObservableCollection(例如 DatasetFiles)绑定到视图 class 以合并 CollectionChanged 事件(如果我没记错的话,这是当 GUI 元素绑定到 ObservableCollection?).

时在 WPF 中自动完成

与此同时,我将 ViewModelBase 更改为以下内容:

public abstract class ViewModelBase : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    protected void SetProperty<T>(ref T storage, T value,
        [CallerMemberName] string property = null)
    {
        if (object.Equals(storage, value)) return;
        storage = value;
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(property));
    }

    protected void OnCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(null));
    }
}

任何具有 ObservableCollection 的 ViewModel 然后负责将添加的 OnCollectionChanged() 订阅到 CollectionChanged 事件。 如果有人提出更好的解决方案,我会很感兴趣:)