在 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
事件。
如果有人提出更好的解决方案,我会很感兴趣:)
由于我的 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
?).
与此同时,我将 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
事件。
如果有人提出更好的解决方案,我会很感兴趣:)