这是我用于视图模型集合的内容:
Preface:
您的视图模型对象可以是弱类型的。给IModel
财产object Value {get;}
并将其暴露在ModelViewModel : ViewModel<IModel>
你用于所有人IModel
对象(参见我的ViewModel<T>
实施如下)。如果你有多种组合ObservableCollection<IModel>
, ICollection<Model<T>>
等等,这里显示的框架是一个救星。如果您仍然需要通用视图模型,您可以派生一个ModelViewModel<T> : ModelViewModel
这需要一个Model<T>
在它的构造函数中。创建适当类型的逻辑将进入传递给的转换器ViewModelCollection.Create
below. 请注意,这种设计会造成性能损失。
ModelViewModel CreateModelViewModel(IModel model)
{
Type viewModelType = typeof(ModelViewModel<>).MakeGenericType(model.Type);
ModelViewModel viewModel = Activator.CreateInstance(viewModelType, model);
return viewModel;
}
用法示例:
public class CatalogViewModel : ViewModel<ICatalog>
{
public CatalogViewModel(ICatalog catalog)
: base(catalog)
{
Func<ICatalogProduct, ProductViewModel> viewModelFactory = CreateProductViewModel;
this.Products = ViewModelCollection.Create(catalog.Products, viewModelFactory);
}
public ICollection<ProductViewModel> Products
{
get;
private set;
}
private ProductViewModel CreateProductViewModel(ICatalogProduct product)
{
return new ProductViewModel(product, this);
}
}
好处:
- 使用惰性实现来允许树中的高效甚至递归绑定。
- 视图模型集合仅实现
INotifyCollectionChanged
如果底层模型集合实现INotifyCollectionChanged
.
类概述(链接到 github 的完整实现):
ViewModel<TModel> http://github.com/280Z28/Application-Foundations/blob/master/Mvvm/ViewModel%601.cs:我的视图模型类的基类。暴露了一个Model
我在视图模型的支持代码中使用的属性。
ObservableViewModelCollection<TViewModel, TModel> http://github.com/280Z28/Application-Foundations/blob/master/Mvvm/ObservableViewModelCollection%602.cs: Lazy(实际上目前还没有,但绝对应该是),可观察到的从模型到视图模型的映射。实施INotifyCollectionChanged
.
ViewModelCollection<TViewModel, TModel> http://github.com/280Z28/Application-Foundations/blob/master/Mvvm/ViewModelCollection%602.cs: Lazy从 TModel 集合映射到TViewModel
.
ViewModelCollection http://github.com/280Z28/Application-Foundations/blob/master/Mvvm/ViewModelCollection.cs:静态助手 - 返回一个ICollection<TViewModel>
, using ObservableViewModelCollection<TViewModel, TModel>
当源集合实现时INotifyCollectionChanged
,否则使用ViewModelCollection<TViewModel, TModel>
.
一些可能对您的视图模型集合有用的额外类型:
ConcatCollection
:与 ViewModelCollection 一样,这包括一个静态帮助器来自动选择适当的实现。 ConcatCollection 通过直接绑定到源集合来连接集合。
- ConcatCollection http://github.com/280Z28/Application-Foundations/blob/master/Mvvm/ConcatCollection.cs
- ConcatCollection<T> http://github.com/280Z28/Application-Foundations/blob/master/Mvvm/ConcatCollection%601.cs
- ObservableConcatCollection<T> http://github.com/280Z28/Application-Foundations/blob/master/Mvvm/ObservableConcatCollection%601.cs
这是我如何使用这种类型来公开的示例Children
属性到视图,同时维护我的可观察集合一直回到原始源。
public class ProductViewModel : ViewModel<IProduct>
{
public ProductViewModel(IProduct product)
: base(product)
{
Func<IProduct, ProductViewModel> productViewModelFactory = CreateProductViewModel;
Func<IRelease, ReleaseViewModel> releaseViewModelFactory = CreateReleaseViewModel;
this.Products = ViewModelCollection.Create(product.Products, productViewModelFactory);
this.Releases = ViewModelCollection.Create(product.Releases, releaseViewModelFactory);
this.Children = ConcatCollection.Create<object>((ICollection)this.Products, (ICollection)this.Releases);
}
public IList<ProductViewModel> Products
{
get;
private set;
}
public IList<ReleaseViewModel> Releases
{
get;
private set;
}
public IEnumerable<object> Children
{
get;
private set;
}
private ProductViewModel CreateProductViewModel(IProduct product)
{
return new ProductViewModel(product);
}
private ReleaseViewModel CreateReleaseViewModel(IRelease release)
{
return new ReleaseViewModel(release);
}
}