[英]IObservableCollection<ViewModel<T>> wrapping ObservableCollection<T>
在C#/ WPF中,提供實現IObservableCollection<ViewModel<T>>
並從模型中包裝ObservableCollection<T>
的類的最佳方法是什么?
模型可以向底層集合添加/刪除T元素,或者視圖可以從視圖模型層添加/刪除ViewModel元素。
從MVVM模式的角度來看,有什么可疑的嗎? 是否有包含此類或類似類的庫?
我在下面編寫了一個類,您可以將其用於單線程目的。 我只實現了添加和刪除,因此您必須實施您可能使用的任何其他操作:...
用法:
var viewModelWrapper = new ObservableCollectionViewModel<ItemViewModel, Model>(Model.List, item => new ItemViewModel(item));
泛型類 - 可觀察集合視圖模型包裝器:
public class ObservableCollectionViewModel<TItemViewModel, TModel> :
ObservableCollection<TItemViewModel>, IDisposable
where TItemViewModel : BaseViewModel<TModel>
where TModel : new()
{
private readonly ObservableCollection<TModel> models;
private readonly Func<TModel, TItemViewModel> viewModelConstructor;
public ObservableCollectionViewModel(ObservableCollection<TModel> models,
Func<TModel, TItemViewModel> viewModelConstructor)
{
this.models = models;
this.viewModelConstructor = viewModelConstructor;
CreateViewModelCollection();
models.CollectionChanged += models_CollectionChanged;
CollectionChanged += viewModels_CollectionChanged;
}
private void viewModels_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
models.CollectionChanged -= models_CollectionChanged;
try
{
switch (e.Action)
{
case NotifyCollectionChangedAction.Add:
{
foreach (var newItem in e.NewItems)
{
models.Add(((TItemViewModel)newItem).Model);
}
break;
}
case NotifyCollectionChangedAction.Remove:
{
foreach (var oldItem in e.OldItems)
{
models.Remove(((TItemViewModel)oldItem).Model);
}
break;
}
// TODO: Add missing actions
default: throw new NotImplementedException();
}
}
finally
{
models.CollectionChanged += models_CollectionChanged;
}
}
private void models_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
CollectionChanged -= viewModels_CollectionChanged;
try
{
switch (e.Action)
{
case NotifyCollectionChangedAction.Add:
{
foreach (var newItem in e.NewItems)
{
Add(viewModelConstructor((TModel)newItem));
}
break;
}
case NotifyCollectionChangedAction.Remove:
{
var viewModels = this.Where(viewModel => e.OldItems.Contains(viewModel.Model)).ToList();
foreach (var viewModel in viewModels)
{
Remove(viewModel);
}
break;
}
// TODO: Add missing actions
default: throw new NotImplementedException();
}
}
finally
{
CollectionChanged += viewModels_CollectionChanged;
}
}
/// <summary>
/// Only called once, by constructor
/// </summary>
private void CreateViewModelCollection()
{
foreach (var model in models)
{
Add(viewModelConstructor(model));
}
}
public void Dispose()
{
models.CollectionChanged -= models_CollectionChanged;
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.